Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

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.

Notifications You must be signed in to change notification settings

ivangfr/springboot-react-keycloak

Repository files navigation

springboot-react-keycloak

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.

Proof-of-Concepts & Articles

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.

Additional Readings

Project diagram

project-diagram

Applications

  • movies-api

    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
  • movies-ui

    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.

Prerequisites

  • Java 21 or higher;

  • npm

  • A containerization tool (e.g., Docker, Podman, etc.)

  • jq

  • 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>
    

PKCE

As Keycloak supports PKCE (Proof Key for Code Exchange) since version 7.0.0, we are using it in this project.

Start Environment

In a terminal, navigate to the springboot-react-keycloak root folder and run:

./init-environment.sh

Initialize Keycloak

In a terminal and inside the springboot-react-keycloak root folder run:

./init-keycloak.sh

This script will:

  • create company-services realm;
  • disable the required action Verify Profile;
  • create movies-app client;
  • create the client role MOVIES_USER for the movies-app client;
  • create the client role MOVIES_ADMIN for the movies-app client;
  • create USERS group;
  • create ADMINS group;
  • add USERS group as realm default group;
  • assign MOVIES_USER client role to USERS group;
  • assign MOVIES_USER and MOVIES_ADMIN client roles to ADMINS group;
  • create user user;
  • assign USERS group to user;
  • create admin user;
  • assign ADMINS group to admin.

Running movies-app using Maven & Npm

  • 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

Applications URLs

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

Demo

  • The gif below shows an admin logging in and adding one movie using the wizard feature:

    demo-admin

  • The gif below shows a user logging in using his Github account; then he changes his avatar and comment on a movie:

    demo-user-github

Testing movies-api endpoints

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.

Getting Access Token

  • 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 JWT access token.

Calling movies-api endpoints using curl

  • 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": []
      }
    ]
    

Calling movies-api endpoints using Swagger

  • 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.

Useful Commands

  • MongoDB

    List all movies:

    docker exec -it mongodb mongosh moviesdb
    db.movies.find()

    Type exit to exit of MongoDB shell.

Shutdown

  • 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

How to upgrade movies-ui dependencies to latest version

  • 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

About

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.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Sponsor this project

 

Packages

No packages published
Morty Proxy This is a proxified and sanitized view of the page, visit original site.