Loading repository data…
Loading repository data…
ivangfr / repository
The goal of this project is to secure movies-app using Keycloak (with PKCE). movies-app consists of two applications: one is a Spring Boot Rest API called movies-api and another is a React application called movies-ui.
The goal of this project is to secure movies-app using Keycloak(with PKCE). movies-app consists of two applications: one is a Spring Boot Rest API called movies-api and another is a React application called movies-ui.
On ivangfr.github.io, I have compiled my Proof-of-Concepts (PoCs) and articles. You can easily search for the technology you are interested in by using the filter. Who knows, perhaps I have already implemented a PoC or written an article about what you are looking for.
Spring Boot Web Java backend application that exposes a REST API to manage movies. Its secured endpoints can just be accessed if an access token (JWT) issued by Keycloak is provided.
movies-api stores its data in a Mongo database.
movie-api has the following endpoints:
| Endpoint | Secured | Roles |
|---|---|---|
GET /api/userextras/me | Yes | MOVIES_ADMIN and MOVIES_USER |
POST /api/userextras/me -d {avatar} | Yes | MOVIES_ADMIN and MOVIES_USER |
GET /api/movies | No | |
GET /api/movies/{imdbId} | No | |
POST /api/movies -d {"imdb","title","director","year","poster"} | Yes | MOVIES_ADMIN |
DELETE /api/movies/{imdbId} | Yes | MOVIES_ADMIN |
POST /api/movies/{imdbId}/comments -d {"text"} | Yes | MOVIES_ADMIN and MOVIES_USER |
React frontend application where users can see and comment movies and admins can manage movies. To access the application, user / admin must login using his/her username and password. Those credentials are managed by Keycloak. All the requests from movies-ui to secured endpoints in movies-api include an access token (JWT) that is generated when user / admin logs in.
movies-ui uses Semantic UI React as CSS-styled framework.
Java 25 or higher;
OMDb API KEY
To use the Wizard option to search and add a movie, we need to get an API KEY from OMDb API. To do this, access https://www.omdbapi.com/apikey.aspx and follow the steps provided by the website.
Once we have the API KEY, create a file called .env.local in the springboot-react-keycloak/movies-ui folder with the following content:
REACT_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, navigate to the springboot-react-keycloak root folder and run:
./init-environment.sh
In a terminal and inside the springboot-react-keycloak root folder run:
./init-keycloak.sh
This script will:
company-services realm;Verify Profile;movies-app client;MOVIES_USER for the movies-app client;MOVIES_ADMIN for the movies-app client;USERS group;ADMINS group;USERS group as realm default group;MOVIES_USER client role to USERS group;MOVIES_USER and MOVIES_ADMIN client roles to ADMINS group;user user;USERS group to user;admin user;ADMINS group to admin.movies-api
Open a terminal and navigate to the springboot-react-keycloak/movies-api folder;
Run the following Maven command to start the application:
./mvnw clean spring-boot:run -Dspring-boot.run.jvmArguments="-Dserver.port=9080"
We can also configure Social Identity Providers such as, GitHub, Google, Facebook and Instagram. I've written two articles in Medium where I explain step-by-step how to integrate GitHub and Google.
movies-ui
Open another terminal and navigate to the springboot-react-keycloak/movies-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 application:
npm start
| Application | URL | Credentials |
|---|---|---|
| movie-api | http://localhost:9080/swagger-ui.html | Access Token |
| movie-ui | http://localhost:3000 | admin/admin or user/user |
| Keycloak | http://localhost:8080 | admin/admin |
The gif below shows an admin logging in and adding one movie using the wizard feature:
The gif below shows a user logging in using his Github account; then he changes his avatar and comment on a movie:
We can manage movies by directly accessing movies-api endpoints using the Swagger website or curl. For the secured endpoints like POST /api/movies, PUT /api/movies/{id}, DELETE /api/movies/{id}, etc, we 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=movies-app" | jq -r .access_token)"
echo $ACCESS_TOKEN
Note: In jwt.io, we can decode and verify the
JWTaccess token.
Trying to add a movie without access token:
curl -i -X POST "http://localhost:9080/api/movies" \
-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 movie, now with access token (obtained at getting-access-token):
curl -i -X POST "http://localhost:9080/api/movies" \
-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",
"comments": []
}
Getting the list of movies. This endpoint does not require access token:
curl -i http://localhost:9080/api/movies
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 movies-api Swagger website, http://localhost:9080/swagger-ui.html.
Click Authorize button.
In the form that opens, paste the access token (obtained at getting-access-token) in the Value field. Then, click Authorize and Close to finalize.
Done! We can now access the secured endpoints.
MongoDB
List all movies:
docker exec -it mongodb mongosh moviesdb
db.movies.find()
Type
exitto exit of MongoDB shell.
To stop movies-api and movies-ui, go to the terminals where they are running and press Ctrl+C;
To stop and remove docker containers, network and volumes, go to a terminal and, inside the springboot-react-keycloak root folder, run the command below:
./shutdown-environment.sh
In a terminal, make sure you are in the springboot-react-keycloak/movies-ui folder;
Run the following commands:
npm upgrade
npm i -g npm-check-updates
ncu -u
npm install