Skip to content

Navigation Menu

Sign in
Appearance settings

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

Sign up
Appearance settings

The goals of this project are to: 1) Create a Spring Boot application that manages books, called book-service; 2) Use Keycloak as OpenID Connect provider; 3) Test using Testcontainers; 4) Explore the utilities and annotations that Spring Boot provides for testing applications.

Notifications You must be signed in to change notification settings

ivangfr/springboot-keycloak-mongodb-testcontainers

Repository files navigation

springboot-keycloak-mongodb-testcontainers

The goals of this project are:

  • Create a Spring Boot application that manages books, called book-service;
  • Use Keycloak as OpenID Connect provider;
  • Test using Testcontainers;
  • Explore the utilities and annotations that Spring Boot provides for testing applications.

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

Application

  • book-service

    Spring Boot Web application that manages books. MongoDB is used as storage, and the application's sensitive endpoints (like create, update and delete books) are secured.

    book-service-swagger

Prerequisites

Start Environment

Open a terminal and, inside the springboot-keycloak-mongodb-testcontainers root folder, run the script below

./init-environment.sh

Configure Keycloak

There are two ways: running a script or using the Keycloak website

Running Script

  • In a terminal, make sure you are inside the springboot-keycloak-mongodb-testcontainers root folder

  • Run the following script to configure Keycloak for book-service application

    ./init-keycloak.sh

    This script will create:

    • company-services realm;
    • book-service client;
    • manage_books client role;
    • user with username ivan.franchin and password 123 and with the role manage_books assigned.
  • The book-service client secret (BOOK_SERVICE_CLIENT_SECRET) is shown at the end of the execution. It will be used in the next step.

  • You can check the configuration in Keycloak by accessing http://localhost:8080. The credentials are admin/admin.

Using Keycloak Website

Login

Create a new Realm

  • On the left menu, click the dropdown button that contains Keycloak and then, click Create Realm button
  • Set company-services to the Realm name field and click Create button

Disable Required Action Verify Profile

  • On the left menu, click Authentication
  • Select Required actions tab
  • Disable Verify Profile

Create a new Client

  • On the left menu, click Clients
  • Click Create client button
  • In General Settings
    • Set book-service to Client ID
    • Click Next button
  • In Capability config
    • Enable Client authentication toggle switch
    • Click Next button
  • In Login settings tab
    • Set http://localhost:9080/* to Valid redirect URIs
    • Click Save button
  • In Credentials tab, you can find the secret generated for book-service
  • In Roles tab
    • Click Create role button
    • Set manage_books to Role Name
    • Click Save button

Create a new User

  • On the left menu, click Users
  • Click Create new user button
  • Set ivan.franchin to Username field
  • Click Create
  • In Credentials tab
    • Click Set password button
    • Set the value 123 to Password and Password confirmation
    • Disable the Temporary toggle switch
    • Click Save button
    • Confirm by clicking Save password button
  • In Role Mappings tab
    • Click Assign role button
    • Click Filter by realm roles dropdown button and select Filter by clients
    • Select [book-service] manage_books name and click Assign button

Running book-service with Gradle

  • Open a new terminal and navigate to the springboot-keycloak-mongodb-testcontainers root folder

  • Run the following command to start the application

    ./gradlew book-service:clean book-service:bootRun --args='--server.port=9080'

Running book-service as a Docker Container

  • In a terminal, navigate to the springboot-keycloak-mongodb-testcontainers root folder

  • Build Docker Image

    ./build-docker-images.sh
    Environment Variable Description
    MONGODB_HOST Specify host of the Mongo database to use (default localhost)
    MONGODB_PORT Specify port of the Mongo database to use (default 27017)
    KEYCLOAK_HOST Specify host of the Keycloak to use (default localhost)
    KEYCLOAK_PORT Specify port of the Keycloak to use (default 8080)
  • Run book-service docker container, joining it to project Docker network

    docker run --rm --name book-service \
     -p 9080:8080 \
     -e MONGODB_HOST=mongodb \
     -e KEYCLOAK_HOST=keycloak \
     --network=springboot-keycloak-mongodb-testcontainers-net \
     ivanfranchin/book-service:1.0.0

Getting Access Token

  • In a terminal, create an environment variable that contains the Client Secret generated by Keycloak to book-service at Configure Keycloak step

    BOOK_SERVICE_CLIENT_SECRET=...
  • When running book-service with Gradle

    Run the commands below to get an access token for ivan.franchin

    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=ivan.franchin" \
     -d "password=123" \
     -d "grant_type=password" \
     -d "client_secret=$BOOK_SERVICE_CLIENT_SECRET" \
     -d "client_id=book-service" | jq -r .access_token)
    echo $ACCESS_TOKEN
  • When running book-service as a Docker Container

    Run the commands below to get an access token for ivan.franchin

    ACCESS_TOKEN=$(
     docker run -t --rm -e CLIENT_SECRET=$BOOK_SERVICE_CLIENT_SECRET --network springboot-keycloak-mongodb-testcontainers-net alpine/curl:latest sh -c '
     curl -s -X POST http://keycloak:8080/realms/company-services/protocol/openid-connect/token \
     -H "Content-Type: application/x-www-form-urlencoded" \
     -d "username=ivan.franchin" \
     -d "password=123" \
     -d "grant_type=password" \
     -d "client_secret=$CLIENT_SECRET" \
     -d "client_id=book-service"' | jq -r .access_token)
    echo $ACCESS_TOKEN

    Note: We are running a alpine/curl Docker container and joining it to the project Docker network. By specifying "keycloak:8080" as host/port, we won't encounter the error related to an invalid token issuer.

  • In jwt.io, you can decode and verify the JWT access token

Test using cURL

  • In terminal, call the endpoint GET /api/books

    curl -i http://localhost:9080/api/books

    It should return:

    HTTP/1.1 200
    []
    
  • Try to call the endpoint POST /api/books, without access token

    curl -i -X POST http://localhost:9080/api/books \
     -H "Content-Type: application/json" \
     -d '{"authorName": "Ivan Franchin", "title": "Java 8", "price": 10.5}'

    It should return:

    HTTP/1.1 401
    
  • Get the Access Token as explained on section Getting Access Token

  • Call the endpoint POST /api/books, now informing the access token

    curl -i -X POST http://localhost:9080/api/books \
     -H "Authorization: Bearer $ACCESS_TOKEN" \
     -H "Content-Type: application/json" \
     -d '{"authorName": "Ivan Franchin", "title": "Java 8", "price": 10.5}'

    It should return something like:

    HTTP/1.1 201
    {"id":"612f4f9438e39e473c4d098b", "authorName":"Ivan Franchin", "title":"Java 8", "price":10.5}
    

Test using Swagger

  • Access http://localhost:9080/swagger-ui.html

  • Click GET /api/books to open it. Then, click Try it out button and, finally, click Execute button.

    It will return a HTTP status code 200 and an empty list or a list with some books if you've already added them.

  • Now, let's try to call a secured endpoint without authentication. Click POST /api/books to open it. Then, click Try it out button (you can use the default values) and, finally, click Execute button.

    It will return:

    Code: 401
    Details: Error: response status is 401
    
  • Get the Access Token as explained on section Getting Access Token

  • Copy the token generated and go back to Swagger

  • Click the Authorize button and paste the access token in the Value field. Then, click Authorize and, to finalize, click Close

  • Go to POST /api/books, click Try it out and, finally, click Execute button.

    It should return something like:

    HTTP/1.1 201
    {
     "id": "612f502f38e39e473c4d098c",
     "authorName": "Ivan Franchin",
     "title": "SpringBoot",
     "price": 10.5
    }
    

Useful Links & Commands

  • MongoDB

    List books

    docker exec -it mongodb mongosh bookdb
    db.books.find()

    Type exit to get out of MongoDB shell

Shutdown

  • To stop book-service, go to the terminal where the application is running and press Ctrl+C;
  • To stop the Docker containers started using the ./init-environment.sh script, make sure you are in springboot-keycloak-mongodb-testcontainers and run the script below:
    ./shutdown-environment.sh

Cleanup

To remove the Docker image created by this project, go to a terminal and, inside the springboot-keycloak-mongodb-testcontainers root folder, run the following script:

./remove-docker-images.sh

Running Unit and Integration Tests

  • In a terminal and inside the springboot-keycloak-mongodb-testcontainers root folder, run the command below to run unit and integration tests

    ./gradlew book-service:clean book-service:assemble \
     book-service:cleanTest \
     book-service:test \
     book-service:integrationTest

    Note: During integration tests, Testcontainers will automatically start MongoDB and Keycloak containers before the tests begin and shut them down when the tests finish.

  • From the springboot-keycloak-mongodb-testcontainers root folder, the Unit Testing Report can be found at:

    book-service/build/reports/tests/test/index.html
    
  • From the springboot-keycloak-mongodb-testcontainers root folder, the Integration Testing Report can be found at:

    book-service/build/reports/tests/integrationTest/index.html
    

About

The goals of this project are to: 1) Create a Spring Boot application that manages books, called book-service; 2) Use Keycloak as OpenID Connect provider; 3) Test using Testcontainers; 4) Explore the utilities and annotations that Spring Boot provides for testing applications.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Sponsor this project

Packages

No packages published

AltStyle によって変換されたページ (->オリジナル) /