JWT Authentication for a Spring Boot Application using Asgardeo — Part 1

Chinthaka Weerakkody
7 min readMar 30, 2023

This medium will provide you a Step by Step guide on how to use JWT authentication for a spring boot application using Asgardeo as the authorization server. The whole content will be covered in two mediums and this is the first medium out of two. This medium will cover the following .

  • Basic concepts of JWT authentication
  • How the Oauth2 Resource Server Feature can be used to protect Spring Boot URIs with JWT authentication
  • Setting up a sample spring boot application to protect with oauth2 resource server feature.

OAuth 2.0 is a widely used authorization protocol. It is designed for an application or a web-site to gain access to resources hosted by some other application or a web-site on behalf of a user. Refer to below medium if you need to read further on Oauth 2.0.

As described in the above OAuth 2.0 medium, the authorization server issues an access token to the application once the user is successfully authenticated. This access token is then used by the application to request resources available in the resource server. When a resource request is made, the application sends the access token in the Authorization header of each request to the resource server. Once the resource server receives this token, it checks the validity of the token.

There are two main types of token formats. The first type is a opaque token, which is a unique random string generated by the Authorization Server. These opaque tokens doesn’t contain any information in it. When an application retrieves this opaque token, the application may need to check the validity of the token and to retrieve additional information about token. Introspection is the process which is being used to achieve this requirement in which the retrieved token is sent to the introspection endpoint of the Authorization Server and in response, the authorization server sends the validity of the token along with the other data determined when the token was issued.

The other token format is the Json Web Token (JWT) format. JWT tokens are self-contained access tokens which means the authorization information is included in the token itself. Therefore, application doesn’t need to invoke the Authorization server to retrieve authorization information as in Opaque token. JWT is an open standard defined in RFC-7519. Also JWT is a signed token. Therefore, the application can check the authenticity of the token by verifying the signature of the token and the issuer of the token.

JWT consists of three components.

  1. Header
  2. Body/Payload
  3. Signature

Its format is like below

<header>.<body>.<signature>

Usually the Authorization Server uses its private key to generate the signature of the JWT token and the client which consumes that JWT token requires the public key of the Authorization Server to check the authenticity of the JWT token. The JWKS endpoint available in Authorization Server can be used to retrieve the public key related information.

The JWKS endpoint is a read only endpoint that responds including the public key set of the Authorization Server. JWT token header includes the unique name of the key which can be used to verify the signature of the token. The client can use that unique name and extract the key set from the response of the JWKS endpoint. Then the client can build the certificate based on the information in the key set and use that certificate to verify the authenticity of the JWT token.

This section discusses on how to protect APIs exposed in a Spring Boot application using JWT authentication. Spring boot can be configured to work as a resource server using the Spring Security’s Oauth2 Resource Server features. This feature can be used to authenticate the the incoming requests for the resource server.

Below diagram illustrates how the interactions in between the different entities occur with respect to the JWT authentication.

Interaction diagram for JWT Authentication

Below lists the sequence of the interaction diagram.

  1. User clicks on the view shopping cart button on the application.
  2. The application requests the shopping cart information from the back end resource server (Spring Boot Application) including the JWT token in the header of the request
  3. Oauth2 Resource Server feature of Spring boot application extracts the JWT token from the request.

4,5 and 6. Oauth2 resource server first checks whether the public key require to generate the signature is available in the cache. If it is not available, then the resource server first invokes the JWKS endpoint of the Authorization server and retrives the key set. Then it will store that key set in the cache for later use and validates the signature of the JWT token.

7,8 and 9. If the JWT authentication is successful, the resource server responds with the shopping cart details and the application will display that information to the user.

10 and 11. If the JWT authentication fails, the resource server responds with the unauthorized error which will be displayed to the user.

Now let’s begin implementation. The implementation section consists of 3 sub sections. First section will focus on setting up the spring boot application. Next section will discuss about setting up the Authorization Server followed up by protecting the api with Oauth2 resource server feature. Finally the article will focus on how to do the testing. This medium will only contain the First Section. Second and third sections will be available in the part 2 of the medium

Setting up Spring Boot Application

  1. Create Spring Boot Project

First use the spring initializer to create a spring boot project. Select Following configurations from the spring initializer.

  • Project Type — Maven
  • Spring boot version — 3.0.5
  • Language — Java
  • Java Version — 17
  • Add Spring Web dependency.
  • Setup the project meta data like Group ID, Artifact ID and name.

Once above is setup Generate the project. This will download the basic project structure. Then import the downloaded project into your preferred IDE.

This spring boot application is a simple online marketplace. There are two main APIs exposed via this application. First API is to list the items available in the marketplace. This is a publicly available API which doesn’t require Authentication. The second API is to get the shopping cart information which is a protected service available only to the logged in users.

2. Create Classes to Represent Item and Shopping Cart

These classes used to create objects of items available in marketplace and the shopping card data. Use Below github links to view the Item and Shopping Card classes.

Item : https://github.com/chinthakarukshan/marketplace/blob/marketplace-without-resourceserver/src/main/java/com/ecommerce/demo/marketplace/dto/Item.java

Shopping Cart : https://github.com/chinthakarukshan/marketplace/blob/marketplace-without-resourceserver/src/main/java/com/ecommerce/demo/marketplace/dto/ShoppingCart.java

3. Create Service Classes for Item handling and Shopping Cart handling

Two interfaces were defined to represent the Item and Shopping Cart Services respectively.

package com.ecommerce.demo.marketplace.service;

import com.ecommerce.demo.marketplace.dto.Item;

import java.util.List;

public interface ShopItemService {

List<Item> getItems();
}
package com.ecommerce.demo.marketplace.service;

import com.ecommerce.demo.marketplace.dto.ShoppingCart;

public interface ShoppingCartService {

ShoppingCart getShoppingCart();
}

Above interfaces were implemented to return predefined set of items and a predefined shopping cart because this project is planned to use for demonstration. Refer to below github links for more information about the respective service implementations.

ShopItemServiceImpl : https://github.com/chinthakarukshan/marketplace/blob/marketplace-without-resourceserver/src/main/java/com/ecommerce/demo/marketplace/service/impl/ShopItemServiceImpl.java

ShoppingCartServiceImpl: https://github.com/chinthakarukshan/marketplace/blob/marketplace-without-resourceserver/src/main/java/com/ecommerce/demo/marketplace/service/impl/ShoppingCartServiceImpl.java

4. Expose the Item and Shopping Cart APIs

This application exposes two REST APIs. One API is to retrive the items available in the marketplace. The second API is to retrieve the shopping cart information of a user.

package com.ecommerce.demo.marketplace.controller;

import com.ecommerce.demo.marketplace.dto.Item;
import com.ecommerce.demo.marketplace.service.ShopItemService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("/item")
public class ShopItemController {

@Autowired
ShopItemService shopItemService;

@GetMapping
public List<Item> getItems() {
return shopItemService.getItems();
}
}
package com.ecommerce.demo.marketplace.controller;

import com.ecommerce.demo.marketplace.dto.ShoppingCart;
import com.ecommerce.demo.marketplace.service.ShoppingCartService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/shoppingcart")
public class ShoppingCartController {

@Autowired
ShoppingCartService shoppingCartService;

@GetMapping
public ShoppingCart getShoppingCart() {
return shoppingCartService.getShoppingCart();
}
}

Additionally, below configurations are added to the application.properties file located inside resources directory. The first line instructs the embedded server to start on port 8080 (This is the default port). The second line instructs the spring boot to use /marketplace as the root of the application.

server.port=8080
server.servlet.contextPath=/marketplace

Now the implementation of the spring boot application is completed.

Testing the Service

Now the spring boot application created in the above section can be tested. Please note that the resource server feature is not enabled in the spring boot application yet and therefore, the above exposed APIs are publicly accessible. Below are the exposed resource URIs and the corresponding responses.

  1. URI for retrieving the items available in the marketplace and the response.
http://localhost:8080/marketplace/item
[
{
"id": 1,
"itemCode": "BOOK-0001",
"itemName": "The Perception Myth",
"price": 670,
"category": "Book"
},
{
"id": 1,
"itemCode": "TOY-0010",
"itemName": "Remote Car",
"price": 1500,
"category": "Toys"
},
{
"id": 1,
"itemCode": "TOY-0010",
"itemName": "Remote Car",
"price": 1500,
"category": "Toys"
}
]

2. URI to retrieve the shopping cart information and the response.

http://localhost:8080/marketplace/shoppingcart
{
"cartId": 12,
"cartItems": [
{
"id": 1,
"itemCode": "TOY-0010",
"itemName": "Remote Car",
"price": 1500,
"category": "Toys"
}
]
}

Full source code up to now can be accessed using below URL.

That concludes the part 01 of this blog. The part 02 of this blog will discuss how to enable resource server for the above developed spring boot application, how to setup Asgardeo to protect the resources and how to do the testing. Please refer to the part 02 of this medium from below link.

--

--