The goal of this project is to secure games-app
using Keycloak
(with PKCE). games-app
consists of two applications: one is a Spring Boot Rest API called games-api
and another is a ReactJS application called games-ui
.
-
Spring Boot
Web Java backend application that exposes a REST API to manage games. Its secured endpoints can just be accessed if an access token (JWT) issued byKeycloak
is provided.games-api
stores its data in aMongo
database.game-api
has the following endpointsEndpoint Secured Roles GET /api/userextras/me
Yes GAMES_MANAGER
andUSER
POST /api/userextras/me -d {avatar}
Yes GAMES_MANAGER
andUSER
GET /api/games
No GET /api/games/{imdbId}
No POST /api/games -d {"imdb","title","director","year","poster"}
Yes GAMES_MANAGER
DELETE /api/games/{imdbId}
Yes MANAGE_GAMES
POST /api/games/{imdbId}/comments -d {"text"}
Yes GAMES_MANAGER
andUSER
-
ReactJS
frontend application whereusers
can see and comment games andadmins
can manage games. In order to access the application,user
/admin
must login using his/her username and password. Those credentials are handled byKeycloak
. All the requests coming fromgames-ui
to secured endpoints ingames-api
have a access token (JWT) that is generated whenuser
/admin
logs in.games-ui
usesSemantic UI React
as CSS-styled framework.
-
OMDb API
KEYTo use the
Wizard
option to search and add a game, you need to get an API KEY from OMDb API. In order to do it, access https://www.omdbapi.com/apikey.aspx and follow the steps provided by the website.Once you have the API KEY, create a file called
.env.local
inspringboot-react-keycloak/games-ui
folder with the following contentREACT_APP_OMDB_API_KEY=<your-api-key>
As Keycloak
supports PKCE
(Proof Key for Code Exchange
) since version 7.0.0
, we are using it in this project.
-
In a terminal and inside
Games Library
root folder rundocker-compose up -d
-
Wait for all Docker containers to be up and running. To check it, run
docker-compose ps
-
games-api
-
Open a terminal and navigate to
Games Library/games-api
folder -
Run the following
Maven
command to start the application./mvnw clean spring-boot:run -Dspring-boot.run.jvmArguments="-Dserver.port=9080"
Once the startup finishes,
KeycloakInitializerRunner.java
class will run and initializecompany-services
realm inKeycloak
. Basically, it will create:- Realm:
company-services
- Client:
games-app
- Client Roles:
GAMES_MANAGER
andUSER
- Two users
admin
: with rolesMANAGE_GAMES
andUSER
user
: only with roleUSER
- Realm:
-
-
games-ui
-
Open another terminal and navigate to
springboot-react-keycloak/games-ui
folder -
Run the command below if you are running the application for the first time
npm install
-
Run the
npm
command below to start the applicationnpm start
-
Application | URL | Credentials |
---|---|---|
games-api | http://localhost:9080/swagger-ui/index.html | Access Token |
games-ui | http://localhost:3000 | admin/admin or user/user |
Keycloak | http://localhost:8080/admin | admin/admin |
You can manage games by accessing directly games-api
endpoints using the Swagger website or curl
. However, for the secured endpoints like POST /api/games
, PUT /api/games/{id}
, DELETE /api/games/{id}
, etc, you need to inform an access token issued by Keycloak
.
-
Open a terminal
-
Run the following commands to get the access token
ACCESS_TOKEN="$(curl -s -X POST \ "http://localhost:8080/realms/company-services/protocol/openid-connect/token" \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "username=admin" \ -d "password=admin" \ -d "grant_type=password" \ -d "client_id=games-app" | jq -r .access_token)" echo $ACCESS_TOKEN
-
Trying to add a game without access token
curl -i -X POST "http://localhost:9080/api/games" \ -H "Content-Type: application/json" \ -d '{ "imdbId": "tt5580036", "title": "I, Tonya", "director": "Craig Gillespie", "year": 2017, "poster": "https://m.media-amazon.com/images/M/MV5BMjI5MDY1NjYzMl5BMl5BanBnXkFtZTgwNjIzNDAxNDM@._V1_SX300.jpg"}'
It should return
HTTP/1.1 401
-
Trying again to add a game, now with access token (obtained at #getting-access-token)
curl -i -X POST "http://localhost:9080/api/games" \ -H "Authorization: Bearer $ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "imdbId": "tt5580036", "title": "I, Tonya", "director": "Craig Gillespie", "year": 2017, "poster": "https://m.media-amazon.com/images/M/MV5BMjI5MDY1NjYzMl5BMl5BanBnXkFtZTgwNjIzNDAxNDM@._V1_SX300.jpg"}'
It should return
HTTP/1.1 201 { "imdbId": "tt5580036", "title": "I, Tonya", "director": "Craig Gillespie", "year": "2017", "poster": "https://m.media-amazon.com/images/M/MV5BMjI5MDY1NjYzMl5BMl5BanBnXkFtZTgwNjIzNDAxNDM@._V1_SX300.jpg" }
-
Getting the list of games. This endpoint does not requires access token
curl -i http://localhost:9080/api/games
It should return
HTTP/1.1 200 [ { "imdbId": "tt5580036", "title": "I, Tonya", "director": "Craig Gillespie", "year": "2017", "poster": "https://m.media-amazon.com/images/M/MV5BMjI5MDY1NjYzMl5BMl5BanBnXkFtZTgwNjIzNDAxNDM@._V1_SX300.jpg", "comments": [] } ]
-
Access
games-api
Swagger website, http://localhost:9080/swagger-ui/index.html -
Click
Authorize
button. -
In the form that opens, paste the
access token
(obtained at getting-access-token) in theValue
field. Then, clickAuthorize
andClose
to finalize. -
Done! You can now access the secured endpoints
-
MongoDB
List all games
docker exec -it mongodb mongo gamesdb db.games.find()
Type
exit
to get out of MongoDB shell
-
To stop
games-api
andgames-ui
, go to the terminals where they are running and pressCtrl+C
-
To stop and remove docker-compose containers, network and volumes, go to a terminal and, inside
springboot-react-keycloak
root folder, run the command belowdocker-compose down -v
-
In a terminal, make sure you are in
springboot-react-keycloak/games-ui
folder -
Run the following commands
npm upgrade npm i -g npm-check-updates ncu -u npm install
- Social Identity Providers like
Google
,Facebook
,Twitter
,GitHub
, etc can be configured by following the steps described inKeycloak
Documentation