- Maven 3
- JDK 21
Use https://jwt.io to decode your generated token
Use https://base64encode.org to encode/decode to/from Base64
./gradlew clean build
docker build ./ -t oauth-service-app
java -jar ./build/libs/auth-server-0.1-SNAPSHOT.jar --auth.profile=mvpd
java -jar ./build/libs/auth-server-0.1-SNAPSHOT.jar --auth.profile=ott
docker-compose up
docker-compose up --build --force-recreate --no-deps
- Client:
entitlements
- Secret:
ott
(forauth.profile=ott
)mvpd
(forauth.profile=mvpd
)
- Username / password:
alice/password
bob/password
clara/password
See this article for info about different types of OAuth 2.0 grants
Authorize using login form on authorization server, get authorization code, exchange it to access token. Very familiar if you’ve ever signed into an application using your Facebook or Google account.
The state
here is CSRF token. This parameter is optional but recommended. You should store the value of the CSRF token
in the user’s session to be validated when they return.
The user will then be asked to login to the authorization server and approve the client.
Put bob/ott
login/password pair into form and click Approve
(The login/password pairs populated into in-memory DB H2. For details check sql scripts in resources folder if needed)
If the user approves the client they will be redirected from the authorisation server back to the client (specifically
to the redirect URI).
After some delay (due to redirection to some fake non-existing resource localhost:9191) you get string like next in
browser address field:
http://localhost:9191/x?code=qjGBjC&state=abc-123.
Get code qjGBjC
for future reuse in next actions.
The returned state abc-123
used to compare with the state parameter sent in the original request.
Use the following generic command to generate an access token:
For this specific application, to generate an access token for the user bob, run next command:
curl http://localhost:9090/oauth/token \
-H "Content-type: application/x-www-form-urlencoded" \
-d 'grant_type=authorization_code&redirect_uri=http://localhost:9191/x&code=qjGBjC' \
-u entitlements:ott
As you see - already generated for bob code qjGBjC
was used
You'll receive responses similar to below
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsibm9uX3BpaV9pZCJdLCJ1c2VyX25hbWUiOiJib2IiLCJzY29wZSI6WyJyZWFkIl0sImV4cCI6MTU4NTIyOTMyOCwiYXV0aG9yaXRpZXMiOlsiUk9MRV9VU0VSIl0sImp0aSI6IjIxODEwZWUxLWI5MGQtNDQ4My1hYTE1LTJlNjZkOTc4MjhlZSIsImNsaWVudF9pZCI6ImVudGl0bGVtZW50cyIsIm5vbl9waWlfaWQiOiIyZjgtNGRhIn0.5Ef4wabYaGi5Ed56kD9bLip92BDx6-WeKNfmwh7P-wI",
"token_type": "bearer",
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsibm9uX3BpaV9pZCJdLCJ1c2VyX25hbWUiOiJib2IiLCJzY29wZSI6WyJyZWFkIl0sImF0aSI6IjIxODEwZWUxLWI5MGQtNDQ4My1hYTE1LTJlNjZkOTc4MjhlZSIsImV4cCI6MTU4NzczNDkyOCwiYXV0aG9yaXRpZXMiOlsiUk9MRV9VU0VSIl0sImp0aSI6ImFmOTk4NzNlLTVkMzItNDk1MS04YWFmLWFjN2VjYmViZjE4YiIsImNsaWVudF9pZCI6ImVudGl0bGVtZW50cyIsIm5vbl9waWlfaWQiOiIyZjgtNGRhIn0.pwDQPzq_pMzOMb5f_0GcZWo_mcd2ncT4oI-qbneOI_Y",
"expires_in": 86399,
"scope": "read",
"non_pii_id": "2f8-4da",
"jti": "21810ee1-b90d-4483-aa15-2e66d97828ee"
}
Get access token using login/password. Used for trusted first party clients both on the web and in native device applications.
curl -X POST http://localhost:9090/oauth/token \
-H 'Authorization: Basic ZW50aXRsZW1lbnRzOm90dA==' \
-H 'Content-type: application/x-www-form-urlencoded' \
-d 'grant_type=password' -d 'username=bob' -d 'password=ott'
Here we use header for basic authorization client_name:client_secret encoded into Base64:
entitlements:ott -> ZW50aXRsZW1lbnRzOm90dA==
You'll receive response similar to below
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsic3Vic2NyaXB0aW9ucyIsInVzZXJzIl0sInVzZXJfbmFtZSI6ImJvYiIsInNjb3BlIjpbInJlYWQiXSwiZXhwIjoxNjUwNzA1MzY3LCJhdXRob3JpdGllcyI6WyJST0xFX1VTRVIiXSwianRpIjoiM2MwNjA2MjctM2FiNy00YTQyLTg4MmMtMjA4OWJkZjBlZTg1IiwiY2xpZW50X2lkIjoiZW50aXRsZW1lbnRzIiwibm9uX3BpaV9pZCI6IjJmOC00ZGEifQ.l_VgIDAXEuJu7Osv6mxmFv0J--MVJ7ZL8PwgnH-l2e0",
"token_type": "bearer",
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsic3Vic2NyaXB0aW9ucyIsInVzZXJzIl0sInVzZXJfbmFtZSI6ImJvYiIsInNjb3BlIjpbInJlYWQiXSwiYXRpIjoiM2MwNjA2MjctM2FiNy00YTQyLTg4MmMtMjA4OWJkZjBlZTg1IiwiZXhwIjoxNjUzMjEwOTY3LCJhdXRob3JpdGllcyI6WyJST0xFX1VTRVIiXSwianRpIjoiNTI2YjBiY2YtYzc5OS00NzBlLThkNmYtNzY0ZGMzZDQ4NTI0IiwiY2xpZW50X2lkIjoiZW50aXRsZW1lbnRzIiwibm9uX3BpaV9pZCI6IjJmOC00ZGEifQ.NlH1NftfyuQLQ3sGwrzVL5wg9alvIS_2MOnSMpxrWZg",
"expires_in": 86399,
"scope": "read",
"non_pii_id": "2f8-4da",
"jti": "3c060627-3ab7-4a42-882c-2089bdf0ee85"
}
The simplest of OAuth 2.0 grants, it is suitable for machine-to-machine authentication where a specific user’s permission to access data is not required.
curl -X POST http://localhost:9090/oauth/token \
-H 'Authorization: Basic ZW50aXRsZW1lbnRzOm90dA==' \
-H "Content-type: application/x-www-form-urlencoded" \
-d 'grant_type=client_credentials'
Here we use header for basic authorization client_name:client_secret encoded into Base64:
entitlements:ott -> ZW50aXRsZW1lbnRzOm90dA==
You'll receive response similar to below
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsic3Vic2NyaXB0aW9ucyIsInVzZXJzIl0sInNjb3BlIjpbInJlYWQiXSwiZXhwIjoxNjUwNzA1MTQ5LCJqdGkiOiJmNGY3MWJmNy04YmRlLTQ0YWYtOGI5Zi00NzY1YzY0OGFlNmYiLCJjbGllbnRfaWQiOiJlbnRpdGxlbWVudHMifQ.kJXmS4e0dNzzYnJayKwH3VMU1bYnAa2ENV1aNMnIzAQ",
"token_type": "bearer",
"expires_in": 86399,
"scope": "read",
"jti": "f4f71bf7-8bde-44af-8b9f-4765c648ae6f"
}
To check existing token use:
curl -X POST client:secret@localhost:9090/oauth/check_token?token=TOKEN_HERE
For our case it should be:
curl -X POST entitlements:ott@localhost:9090/oauth/check_token?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsibm9uX3BpaV9pZCJdLCJ1c2VyX25hbWUiOiJib2IiLCJzY29wZSI6WyJyZWFkIl0sImV4cCI6MTU4NTIyOTMyOCwiYXV0aG9yaXRpZXMiOlsiUk9MRV9VU0VSIl0sImp0aSI6IjIxODEwZWUxLWI5MGQtNDQ4My1hYTE1LTJlNjZkOTc4MjhlZSIsImNsaWVudF9pZCI6ImVudGl0bGVtZW50cyIsIm5vbl9waWlfaWQiOiIyZjgtNGRhIn0.5Ef4wabYaGi5Ed56kD9bLip92BDx6-WeKNfmwh7P-wI
You'll receive a response similar to below
{
"aud": [
"non_pii_id"
],
"user_name": "bob",
"scope": [
"read"
],
"active": true,
"exp": 1585229328,
"authorities": [
"ROLE_USER"
],
"jti": "21810ee1-b90d-4483-aa15-2e66d97828ee",
"client_id": "entitlements",
"non_pii_id": "2f8-4da"
}
or next
{
"error": "invalid_token",
"error_description": "Encoded token is a 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
For our case it should be:
curl -X POST -d refresh_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsibm9uX3BpaV9pZCJdLCJ1c2VyX25hbWUiOiJib2IiLCJzY29wZSI6WyJyZWFkIl0sImF0aSI6IjIxODEwZWUxLWI5MGQtNDQ4My1hYTE1LTJlNjZkOTc4MjhlZSIsImV4cCI6MTU4NzczNDkyOCwiYXV0aG9yaXRpZXMiOlsiUk9MRV9VU0VSIl0sImp0aSI6ImFmOTk4NzNlLTVkMzItNDk1MS04YWFmLWFjN2VjYmViZjE4YiIsImNsaWVudF9pZCI6ImVudGl0bGVtZW50cyIsIm5vbl9waWlfaWQiOiIyZjgtNGRhIn0.pwDQPzq_pMzOMb5f_0GcZWo_mcd2ncT4oI-qbneOI_Y -d grant_type=refresh_token entitlements:ott@localhost:9090/oauth/token
You'll receive a response similar to below
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsibm9uX3BpaV9pZCJdLCJ1c2VyX25hbWUiOiJib2IiLCJzY29wZSI6WyJyZWFkIl0sImV4cCI6MTU4NTIyOTY5MywiYXV0aG9yaXRpZXMiOlsiUk9MRV9VU0VSIl0sImp0aSI6IjRkMmNmNWIwLWNkZTYtNDgyNS05NWExLTc1MTVkNWM5OTM3OCIsImNsaWVudF9pZCI6ImVudGl0bGVtZW50cyIsIm5vbl9waWlfaWQiOiIyZjgtNGRhIn0.XqP3T4hrROecgNqHIAgL1sBUhraN-I6pM3q0rbJjSus",
"token_type": "bearer",
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsibm9uX3BpaV9pZCJdLCJ1c2VyX25hbWUiOiJib2IiLCJzY29wZSI6WyJyZWFkIl0sImF0aSI6IjRkMmNmNWIwLWNkZTYtNDgyNS05NWExLTc1MTVkNWM5OTM3OCIsImV4cCI6MTU4NzczNDkyOCwiYXV0aG9yaXRpZXMiOlsiUk9MRV9VU0VSIl0sImp0aSI6ImFmOTk4NzNlLTVkMzItNDk1MS04YWFmLWFjN2VjYmViZjE4YiIsImNsaWVudF9pZCI6ImVudGl0bGVtZW50cyIsIm5vbl9waWlfaWQiOiIyZjgtNGRhIn0.XNjkVBwrldmX16ziIgdIZNGGcdrLPoLxkf4YWXxX1xU",
"expires_in": 86399,
"scope": "read",
"non_pii_id": "2f8-4da",
"jti": "4d2cf5b0-cde6-4825-95a1-7515d5c99378"
}
Use the generated token as the value of the Bearer in the Authorization header as follows:
curl http://localhost:9091/YOUR_RESOURCE_PATH -H "Authorization: Bearer ACCESS_TOKEN_HERE"