Spring Boot Security | SSO | OAuth2 with Okta

Amila Iroshan
The Fresh Writes
Published in
8 min readFeb 18, 2023

Introduction

In this article I’ll explain how to integrate okta authentication and authorization server with spring boot web application and how to secure rest API with okta.

The objectives of this application is:

-Provide authentication and authorization to spring boot web application using okta. (allow social login along with Google)
- Authenticate API(Rest end point) with JWT using okta.
- Manage users using okta user management.

What is Single Sign-On?
Single sign-on (SSO) is an authentication method that enables users to securely authenticate with multiple applications and websites by using just one set of credentials.
In breifly it allows users to get one-click secure access to multiple applications using a single username and password.

What is okta ?
Okta is access management system which helps manage and secure user authentication into applications, and for developers to build identity controls into applications, website, web services and devices.

Why we used okta ?
Okta runs in the cloud, on a secure, reliable, extensively audited platform, which integrates deeply with on-premises applications, directories, and identity management systems.
Okta features include Provisioning, Single Sign-On (SSO), Active Directory (AD) and LDAP integration, the centralized deprovisioning of users, multifactor authentication (MFA), mobile identity management, and flexible policies for organization security and control.
Beside that developer do not need to worry about user management, session handling and other security things. All things are provided by okta and we can integrate it into our application quickly.

The Spring security with okta authentication workflow as below.

Authentication flow

Let’s Start,

As first step you have to signup with okta using https://auth0.com/ and this is a easy and stright forward process.
After successful signup you can see your Auth0 Dashboard. Then navigate to Application tab and create a new application.

Okta Dashboard

When click the “Create Application” button system will prompt the below popup dialog and then choose regular web application.

Then you can choose your favorite technology and here I chosen java spring boot.

After done above steps the system will generate your application along with the client-id, client-secret and issuer-uri. Those are specific to your application and later we have to configure these three values with our web application’s security configurations.

Application portal

Then Configure Callback URLs
A callback URL is a URL in your application that you would like Auth0 to redirect users to after they have authenticated.
Eg: http://localhost:8080/login/oauth2/code/auth0.

Configure Logout URLs
A logout URL is a URL in your application that you would like Auth0 to redirect users to after they have logged out.
Eg: http://localhost:8080

Call back URL

Configure Spring Boot application

Create spring boot application.

— Navigate to https://start.spring.io.

— Choose either Gradle or Maven as build tool. In here I’m using Gradle and Java 18.

This is my dependencies on build.gradle

dependencies {

implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server'
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5'
implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect'
implementation 'org.springframework.boot:spring-boot-starter-web-services'
testImplementation 'org.springframework.boot:spring-boot-starter-test'

}

Configure Spring Security
In your application’s configuration, configure the OAuth2 client and provider using application.yml file. Spring Security uses the issuer-uri property value to retrieve the information necessary to enable login and ID token validation at runtime.
This is my application.yml file.

server:
port: 8080

logging:
level:
root: ERROR
org.springframework.web: ERROR
com.auth0.application: TRACE

spring:
security:
oauth2:
client:
registration:
auth0:
client-id: yOe1t513V0TEmUivzRwJ4dE
client-secret: fMeuE1_j1trDSE4mFpXTGGKSmh_-OVikwNmE--MDtCme40Q4AXBzO
scope:

provider:
auth0:

issuer-uri: https://dev-.us.auth0.com/

Then, to enable user login with Auth0, create a class that will provide an instance of SecurityFilterChain, and add the @EnableWebSecurity annotation.

 @Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
// allow all users to access the home pages and the static images directory
.mvcMatchers("/","/login", "/images/**").permitAll()
//allow authentication for exposed rest end point
.mvcMatchers("/api/cartDetails").authenticated()
// all other requests must be authenticated
.anyRequest().authenticated()
// set the login success url
.and().oauth2Login().defaultSuccessUrl("/home", true)
.and().logout()
// handle logout requests at /logout path
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
// customize logout handler to log out of Auth0
.addLogoutHandler(logoutHandler)
.and().cors()
.and().oauth2ResourceServer().jwt();

Add controller
Create a controller to handle the incoming request. In here I’m using rest template as view template.

  @GetMapping("/")
public String home(Model model, @AuthenticationPrincipal OidcUser principal) {
if (principal != null) {
model.addAttribute("profile", principal.getClaims());
}
return "index";
}
@GetMapping("/home")
public String sucessLogin(Model model, @AuthenticationPrincipal OidcUser principal) {
if (principal != null) {
model.addAttribute("profile", principal.getClaims());
model.addAttribute("shopingcart",itemService.getShopingCart());
}
return "home";
}

This controller renders the index.html page when request “/”.
The request login page it render callback url provide okta login page.

login page

Auth0 enables the Google social provider by default on new tenants and offers you developer keys to test logging in with social identity providers.

After enter valid user credentials the user authenticates and application render home.html. When rendering the application retrieves the users profile information and hard coded shopping cart item list attributes to render the page.

home page

When you request the “/profile” you can see all the details of logged user which hold on authentication principle object.

profile page

Add logout to your application
Now that users can log into your application, they need a way to log out. By default, Spring Security logs user out of your application and clears the session when you enable logout. To enable successful Auth0 logout, extend the SecurityContextLogoutHandler class to redirect users to your Auth0 logout endpoint (https://{yourDomain}/v2/logout) and then immediately redirect them to your application.

@Controller
public class LogoutHandler extends SecurityContextLogoutHandler {

private final Logger log = LoggerFactory.getLogger(this.getClass());
private final ClientRegistrationRepository clientRegistrationRepository;
@Autowired
public LogoutHandler(ClientRegistrationRepository clientRegistrationRepository) {
this.clientRegistrationRepository = clientRegistrationRepository;
}
@Override
public void logout(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
Authentication authentication) {

// Invalidate the session and clear the security context
super.logout(httpServletRequest, httpServletResponse, authentication);

// Build the URL to log the user out of Auth0 and redirect them to the home page.
// URL will look like https://YOUR-DOMAIN/v2/logout?clientId=YOUR-CLIENT-ID&returnTo=http://localhost:3000
String issuer = (String) getClientRegistration().getProviderDetails().getConfigurationMetadata().get("issuer");
String clientId = getClientRegistration().getClientId();
String returnTo = ServletUriComponentsBuilder.fromCurrentContextPath().build().toString();

String logoutUrl = UriComponentsBuilder
.fromHttpUrl(issuer + "v2/logout?client_id={clientId}&returnTo={returnTo}")
.encode()
.buildAndExpand(clientId, returnTo)
.toUriString();

log.info("Will attempt to redirect to logout URL: {}", logoutUrl);
try {
httpServletResponse.sendRedirect(logoutUrl);
} catch (IOException ioe) {
log.error("Error redirecting to logout URL", ioe);
}
}

Update your security configuration
Next, update your implementation of SecurityFilterChain to register your logout handler and specify the request path that should trigger logout (/logout in the example below).

 .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
// customize logout handler to log out of Auth0
.addLogoutHandler(logoutHandler)

Cheers ! Now our web application’s security configuration works have been almost done and then we have to create rest end point to expose shopping cart list items. As well as I’m going to secure that API using JWT which is provided by OKTA.

The Rest API Authentication Flow

JWT Authentication Flow

Let’s begin,

Go to api dashboard, It is under the application nav bar. Then click create API button.

Create API

As I mentioned above, create a new api by giving proper name to it and then okta will generate the identifier which is related to particular api.

API Settings

This is my rest controller which expose the shopping cart items.

@RestController
@RequestMapping(path = "api", produces = MediaType.APPLICATION_JSON_VALUE)
@CrossOrigin(origins = "*")
public class APIController {

@Autowired
private ItemService itemService;
@GetMapping(value = "/cartDetails")
public ShoppingCart privateEndpoint() {
return itemService.getShopingCart();
}

But I have secure this api here. Therefore without proper authentication token you are unable to access it.

 .mvcMatchers("/api/cartDetails").authenticated()

How to retrieve JWT access token

You can get jwt token with below request.

HttpResponse<String> response = Unirest.post("https://dev-amila-.us.auth0.com/oauth/token")
.header("content-type", "application/json")
.body("{\"client_id\":\"AVxkJdUnXSSJBcpXlH2ZPfl\",\"client_secret\":\"S5S3SqPVSv5UFa4879djdTG4qpI89PqB_M_7x0F0Jpj\",\"audience\":\"https://Villvay-assignment-api/api\",\"grant_type\":\"client_credentials\"}")
.asString();
JWT request using postman

After getting the jwt you can access secure api along with jwt as header param.

Request data with jwt

Great !! Hopefully you are able to got some idea about how to authenticate spring boot web application using okta.

In addition to that okta provides the user management portal as well. You can create users and roles in your okta dashbord.

Thank you for read this article and If you liked the article, do follow and clap 👏🏻.Happy coding, Cheers !!😊

You can find the complete code for this example on GitHub

Do support our publication by following it

--

--

Amila Iroshan
The Fresh Writes

Software Engineer | Open Source Contributor | Tech Enthusiast