Skip to content

andrei-punko/spring-boot-jwt

 
 

Repository files navigation

An example of Spring Boot application for securing a REST API with JSON Web Token (JWT)

Java CI with Gradle Coverage Branches

Main building blocks

Prerequisites:

  • Maven 3
  • JDK 21

How to build:

./gradlew build

How to build Docker image with oauth-service application inside:

cd oauth-server
docker build ./ -t oauth-service-app
cd..

How to build Docker image with oauth-service application inside:

cd resource-server
docker build ./ -t resource-service-app
cd..

To run the application

java -jar ./oauth-server/build/libs/oauth-server-0.0.1-SNAPSHOT.jar
java -jar ./resource-server/build/libs/resource-server-0.0.1-SNAPSHOT.jar

Or import the project into your IDE and run AuthServerApplication & ResourceServerApplication from there.

Or use docker compose:

docker-compose up

To test the application

First you will need the following basic pieces of information:

  • client: testjwtclientid
  • secret: XY7kmzoNzl100
  • Non-admin username and password: john.doe and jwtpass
  • Admin user: admin.admin and jwtpass
  • Example of resource accessible to all authenticated users: http://localhost:9091/foo/123 (any number here)
  • Example of resource accessible to only an admin user: http://localhost:9091/cities

Generate access token

Use the following generic command to generate an access token:

curl -X POST client:secret@localhost:9090/oauth/token -d grant_type=password -d username=user -d password=pwd

For this specific application, to generate an access token for the non-admin user john.doe, run:

curl -X POST testjwtclientid:XY7kmzoNzl100@localhost:9090/oauth/token -d grant_type=password -d username=john.doe -d password=jwtpass
curl -X POST testjwtclientid:XY7kmzoNzl100@localhost:9090/oauth/token -d grant_type=password -d username=admin.admin -d password=jwtpass

You'll receive responses similar to below

{
    "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsidGVzdGp3dHJlc291cmNlaWQiXSwidXNlcl9uYW1lIjoiYWRtaW4uYWRtaW4iLCJzY29wZSI6WyJyZWFkIiwid3JpdGUiLCJmb28iXSwiZXhwIjoxNTgzODY4MjkwLCJhdXRob3JpdGllcyI6WyJTVEFOREFSRF9VU0VSIiwiQURNSU5fVVNFUiJdLCJqdGkiOiIzYzdmYmM3Ni1mM2VhLTRkYTAtYmRlOC1jYTFlNWY0MzYxMzUiLCJjbGllbnRfaWQiOiJ0ZXN0and0Y2xpZW50aWQifQ.ki0W0_jLX4RqhnqTIdBg1j14yfJOyeipHH9W_7d-WTA",
    "token_type": "bearer",
    "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsidGVzdGp3dHJlc291cmNlaWQiXSwidXNlcl9uYW1lIjoiYWRtaW4uYWRtaW4iLCJzY29wZSI6WyJyZWFkIiwid3JpdGUiLCJmb28iXSwiYXRpIjoiM2M3ZmJjNzYtZjNlYS00ZGEwLWJkZTgtY2ExZTVmNDM2MTM1IiwiZXhwIjoxNTg2NDE3MDkwLCJhdXRob3JpdGllcyI6WyJTVEFOREFSRF9VU0VSIiwiQURNSU5fVVNFUiJdLCJqdGkiOiIwMzQyYzJmOC05MDI0LTQxNzItYWZjZC0wZDhhZjJkMjIxYzQiLCJjbGllbnRfaWQiOiJ0ZXN0and0Y2xpZW50aWQifQ.wEg_JSEn97KulZVbqd2gq-7piacX6JZ_KOilIy0W_Pk",
    "expires_in": 43199,
    "scope": "read write foo",
    "jti": "3c7fbc76-f3ea-4da0-bde8-ca1e5f436135"
}

Check existing token

To check existing token use:

curl -X POST client:secret@localhost:9090/oauth/check_token?token=TOKEN_HERE

You'll receive a response similar to below

{
    "aud": ["testjwtresourceid"],
    "user_name": "admin.admin",
    "scope": ["read", "write", "foo"],
    "exp": 1583866486,
    "authorities": ["STANDARD_USER", "ADMIN_USER"],
    "jti": "6b4ebc1b-ea20-4f5a-a0a4-280f48ce41cc",
    "client_id": "testjwtclientid"
}

or next

{
    "error": "invalid_token",
    "error_description": "Encoded token is a refresh token"
}

Get new token pair using refresh token

To get new token pair using existing refresh token use:

curl -X POST -d refresh_token=REFRESH_TOKEN_HERE -d grant_type=refresh_token client:secret@localhost:9090/oauth/token

You'll receive a response similar to below

{
    "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsidGVzdGp3dHJlc291cmNlaWQiXSwidXNlcl9uYW1lIjoiYWRtaW4uYWRtaW4iLCJzY29wZSI6WyJyZWFkIiwid3JpdGUiLCJmb28iXSwiZXhwIjoxNTgzODcwMjg5LCJhdXRob3JpdGllcyI6WyJTVEFOREFSRF9VU0VSIiwiQURNSU5fVVNFUiJdLCJqdGkiOiI2OTVmZmVmMi01YzQ1LTRmNTAtYmJhNy1kZTMyMWY3OWM5NjUiLCJjbGllbnRfaWQiOiJ0ZXN0and0Y2xpZW50aWQifQ.1aB-ke4dLX1_AdBGzVPtWcG9oOEt3Gptsyz8MrSEp0I",
    "token_type": "bearer",
    "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsidGVzdGp3dHJlc291cmNlaWQiXSwidXNlcl9uYW1lIjoiYWRtaW4uYWRtaW4iLCJzY29wZSI6WyJyZWFkIiwid3JpdGUiLCJmb28iXSwiYXRpIjoiNjk1ZmZlZjItNWM0NS00ZjUwLWJiYTctZGUzMjFmNzljOTY1IiwiZXhwIjoxNTg2NDE4Mzg0LCJhdXRob3JpdGllcyI6WyJTVEFOREFSRF9VU0VSIiwiQURNSU5fVVNFUiJdLCJqdGkiOiJjYTNjN2VkMS0wYmE4LTRhMDUtYTUwZC0wNzNkZmMyN2M0YzIiLCJjbGllbnRfaWQiOiJ0ZXN0and0Y2xpZW50aWQifQ.hXv1I-t1u_eZ3JSv-3tHSkaTzfXb-jRHG3W5sNIfIoc",
    "expires_in": 43199,
    "scope": "read write foo",
    "jti": "695ffef2-5c45-4f50-bba7-de321f79c965"
}

Use tokens to access resources through your RESTful API

Access content available for all authenticated users:

Use the generated tokens as the value of the Bearer in the Authorization header as follows:

curl http://localhost:9091/foos/1 -H "Authorization: Bearer ACCESS_TOKEN_HERE"

The response will be:

{
    "id": 68,
    "name": "rRun"
}

Access content available only for an admin user:

curl http://localhost:9091/cities -H "Authorization: Bearer ACCESS_TOKEN_HERE"

The result will be:

[{
        "id": 1,
        "name": "Bamako"
    }, {
        "id": 2,
        "name": "Nonkon"
    }, {
        "id": 3,
        "name": "Houston"
    }, {
        "id": 4,
        "name": "Toronto"
    }, {
        "id": 5,
        "name": "New York City"
    }, {
        "id": 6,
        "name": "Mopti"
    }, {
        "id": 7,
        "name": "Koulikoro"
    }, {
        "id": 8,
        "name": "Moscow"
    }
]

About

Spring Boot service which REST API secured by JWT

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Java 83.2%
  • Groovy 14.8%
  • Dockerfile 1.4%
  • Batchfile 0.6%
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy