Spring Security 5: OAuth 2.0 Resource Server with JWT

Chandra Sharma
5 min readJun 17, 2021

--

Spring Security JWT
Spring Security JWT Validation

Development team in any organisation starts with API development using plethora of languages and framework available like Spring Boot, Flask, Express and others.

One important thing in terms of complete API Journey is securing our APIs and here comes Spring Security to the rescue.

Ideally, we should take API Security into consideration start from the development.

What is Spring Security?

Spring Security is a powerful and highly customizable authentication and access-control framework. It is the de-facto standard for securing Spring-based applications.

Spring Security is a framework that focuses on providing both authentication and authorization to Java applications.

Spring Security has support for OAuth 2.0 for the following:

OAuth 2.0 Login

The OAuth 2.0 Login feature provides an application with the capability to have users log in to the application by using their existing account at an OAuth 2.0 Provider (e.g. GitHub) or OpenID Connect 1.0 Provider (such as Google).

OAuth 2.0 Resource Server

As a Resource Server, Spring Security 5 provides support for protecting the API endpoints using two forms for OAuth2.0 Bearer Tokens – JWT and Opaque.

OAuth 2.0 Client

The OAuth 2.0 Client features provide support for the Client role as defined in the OAuth 2.0 Authorization Framework.

Spring Security OAuth 2.0 Resource Server

In this story, we will see how we can make use of Spring Security 5 OAuth 2.0 support as resource server to protect the endpoints using JWT as Bearer Token.

Pre-requisites for code along with this tutorial

To gain the concepts from this tutorial, you will be needing the following setup ( no one is stopping from you to read though. So in case you don’t have the setup ready, you can read this tutorial and do the hands-on later).

  • IDE of your choice
  • OAuth 2.0 Authorisation server to issue token in JWT format

You can go through the below Story on Getting Started with Keycloak. It will take only a moment to setup in your local development environment.

Setting up OAuth2.0/ OpenID Client in Keycloak

Once you are logged into Keycloak and able to see Master Realm as shown in the below screenshot.

Keycloak Home Page for Master Realm
Keycloak Home Page for Master Realm

You need to go to Clients Tab to create a new Client.

Keycloak Clients Screen
Keycloak Clients Screen

Once you click create client, you will see below screen. Enter the name for your Client ID (you can give UUID as well here so that your client id is not obvious in different OAuth 2.0 flows)

Create Client Form in Keycloak
Create Client Form in Keycloak

Once we click on save, OAuth client will be created in keycloak and the flow will be navigated to next screen where the option to select Name of Client, Client Access Type and other fields will appear.

Here you need to make few updates:

  • Select Access Type as “confidential”
  • Service Account Enabled as ON for OAuth 2.0 client_credentials grant_type.
Keycloak Client Options
Keycloak Client Options

Generating JWT Access Token

First you need to get the Access Token URL and OpenID provides a discovery endpoint which is also known as well-known openid configuration.

For Keycloak Master realm here is the well known configuration url. In case you are using any other realm, just replace master with the “realm name” that you are on.

http://localhost:8080/realms/master/.well-known/openid-configuration

To generate Access Token, you can use the below curl command by replacing the “Authorizaton” Header value as Base64(client_id:client_secret) as per the Client you have created.


curl -X POST \
http://localhost:8080/realms/master/protocol/openid-connect/token \
-H 'Authorization: Basic c3ByaW5nLXNlY3VyaXR5LWp3dC1kZW1vOmY5Yjk1YzAyLTA1YWYtNGNjMi05MjA3LTNhMWZkMzlkOWU0MQ==' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-H 'Postman-Token: 49d57263-5f46-4a33-bd85-18f10b608165' \
-H 'cache-control: no-cache' \
-d 'grant_type=client_credentials'

Response will look like following from the token endpoint.

{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJGZHQyVl84bEdHZERrcHFSRlp4WkNyRFFCMWF6clBsRWZOOGlTa1dWQVpRIn0.eyJleHAiOjE2MjM4NjkwNTIsImlhdCI6MTYyMzg2ODk5MiwianRpIjoiNzE3YWVmYTMtZjUyNS00YjNhLTkxMzgtM2EwNzQ0YThkODE5IiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy9tYXN0ZXIiLCJhdWQiOlsiZGVtby1jbGllbnQiLCJhY2NvdW50Il0sInN1YiI6IjVmN2I1NzJhLTVkZDktNDRhYy1hNGZlLWVjNDczYjNhOTA0NiIsInR5cCI6IkJlYXJlciIsImF6cCI6InNwcmluZy1zZWN1cml0eS1qd3QtZGVtbyIsImFjciI6IjEiLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsiZGVmYXVsdC1yb2xlcy1tYXN0ZXIiLCJvZmZsaW5lX2FjY2VzcyIsIkRlbW9BcHBSb2xlIiwidW1hX2F1dGhvcml6YXRpb24iXX0sInJlc291cmNlX2FjY2VzcyI6eyJkZW1vLWNsaWVudCI6eyJyb2xlcyI6WyJ1bWFfcHJvdGVjdGlvbiJdfSwiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJwcm9maWxlIGVtYWlsIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJjbGllbnRIb3N0IjoiMTI3LjAuMC4xIiwiY2xpZW50SWQiOiJzcHJpbmctc2VjdXJpdHktand0LWRlbW8iLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJzZXJ2aWNlLWFjY291bnQtc3ByaW5nLXNlY3VyaXR5LWp3dC1kZW1vIiwiY2xpZW50QWRkcmVzcyI6IjEyNy4wLjAuMSJ9.NEY9mLwTi7TjmLrtRQz9zKCXcGmNUMZrlhwgHhOTvFlKTE3PepSLJqS9KVyxMwIQkT-a3Vqp2cHD-0xP-RGPF6z4zEWOD37WWUc94kSkY7sHLTDHfDJa9fLYbXSqWpdv1PrqVgzzbRK-8Rspk6Q2V8z_UE3vpWce2RvYHB4v5HcH6B7_JMNPQBd4yu3XM_NisPQOPMB_GuSwZYkbnKAZnQepxoSLiOBQ7BOYx0M7-Jf7ql6rRDL4TBy6KYqBnXkQ2xaSc28aC9kOWiNuHMTLTyB5y0ocDCrkdpPDUOeAasIIsKY5za-MVbaS1Yq4S3Fhpm6XjOC4qCOL5rbnbphwzw",
"expires_in": 60,
"refresh_expires_in": 0,
"token_type": "Bearer",
"not-before-policy": 0,
"scope": "profile email"
}

By doing all the Keycloak related steps, we are done with the JWT Bearer Access Token.

Minimal Configuration to secure our APIs with JWT Bearer Token

Here is the pom.xml with which you can get started with minimal configuration. Dependencies to note here are “spring-boot-starter-oauth2-resource-server” for enabling OAuth 2.0 Resource server and “spring-security-oauth2-jose” for all the JWT handling.

Now, you need to tell the OAuth 2.0 resource server where it should look for the validation of the JWT. This is done by putting the following in application.properties file.

Add a RestController to create a Hello GET API.

With this setup we are good to go.

Test the security setup we have done

Step 1: Invoke GET /hello API without passing any token. This will give 401 Unauthorized as we have not passed any token

API Call failed 401 Unauthorized
API Call failed 401 Unauthorized

Step 2: Generate a token as mentioned in the Token Generation Step.

Step 3: Set the Authorization type as Bearer and provide the JWT access token got from Step 2.

Successfull API invocation with JWT Bearer Token
Successfull API invocation with JWT Bearer Token

Here you can see that by setting Authorization type as Bearer and passing a valid JWT Token, API invocation is successful.

Also, notice that since we have provided “JwtAuthenticationToken” as argument in the RestController. So, once we have successful Token Validation, Spring Security will set the JWTAuthenticationToken object with which you can access all the JWT Attributes, Principal and other details. Do checkout all the options by playing around in the controller.

That is all for this story. Happy Reading :)

In case you are new to Spring Boot, here is YT playlist to get you started quickly.

--

--

Chandra Sharma

I am a technology explorer who loves to read, hands-on and share the knowledge gained.