Creating an OpenID Connect client with Spring Boot
This document provides a step-by-step guide to creating an OIDC client using Spring Boot and Java.
OpenAthens acts as an OIDC provider, which your application will communicate with. In this example, we will use the Spring Security framework as the OIDC client, however you can use any OIDC compatible client library or plugin.
Notes
This is sample code and is not production-ready
Proper error handling is not implemented
Authorisation is not implemented. This example shows how to obtain the claims necessary to authorise visiting users
You will need to configure your `application.properties` with the details for an application that you will create with the SP Dashboard - https://sp.openathens.net
Step 1: Initialise the Project
This example uses Spring Boot and their Initializr website. You do not need to use Spring Boot, you can use any language, framework, or OIDC client of your choice.
Similarly this has been tested with Java 17 & 21 and Spring Boot 3.4.2. For other frameworks, versions and libraries, please refer to the documentation of your framework of choice.
Use Spring Initializr (https://start.spring.io/) to create a new Spring Boot project with the following dependencies, using Maven:
Spring Web
Spring Security
OAuth2 Client
Make the following changes to the autogenerated project following your desired package structure:
Add an empty Java file OAuth2SecurityConfig.java (step 2)
Add an empty Java file ClaimsDebugController.java (step 3)
Spring Boot should have created a file called
application.yml
orapplication.properties
in resources.
This example uses the YAML style config, so you may need to rename the config file from '.properties' to '.yml'
Step 2: Configure Security
Add the following to OAuth2SecurityConfig.java. This security config tells Spring Security to protect every endpoint except '/' and to route unauthenticated requests via the configured OIDC provider.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
@EnableWebSecurity
public class OAuth2SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity, ClientRegistrationRepository clientRegistrationRepository) throws Exception {
httpSecurity.authorizeHttpRequests(requests ->
requests.requestMatchers("/")
.permitAll()
.anyRequest()
.authenticated())
.oauth2Login(Customizer.withDefaults());
return httpSecurity.build();
}
}
Step 3: Create Controllers
Add the following to ClaimsDebugController.java. This controller simply provides the user claims as a JSON response. In a production application, you would not do this, but rather use the claims obtained to establish whether the authenticated user belongs to a subscribing organisation and should be authorised.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.oauth2.core.oidc.user.OidcUser;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
@RestController
public class ClaimsDebugController {
private final ObjectMapper mapper;
@Autowired
public ClaimsDebugController(ObjectMapper mapper) {
this.mapper = mapper;
}
@GetMapping(value = "/claims", produces = "application/json")
public ResponseEntity<String> get(@AuthenticationPrincipal OidcUser oidcUser) {
try {
return ResponseEntity.ok(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(oidcUser.getClaims()));
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
}
Step 4 Configure an application in the SP Dashboard:
Create an application in the OpenAthens SP Dashboard.
Access the SP dashboard: https://sp.openathens.net/ and create a new OIDC application
In the configuration tab of the OIDC application you created via the SP Dashboard, set the redirect URL to be http://localhost:8080/login/oauth2/code/custom (this assumes you are running locally. Set the domain and port as appropriate)
Keep this tab open for the next step where you will need the client ID and secret
Step 5: Configure `application.yml` in your project
Replace the contents of the application.yml
file with the below.
You ONLY need to replace YOUR_CLIENT_ID and YOUR_CLIENT_SECRET below with the necessary details obtained from the SP dashboard to configure your OIDC client. You may need to rename the default config file from '.properties' to '.yml' though.
spring:
security:
oauth2:
client:
registration:
custom:
client-name: Example
client-id: YOUR_CLIENT_ID
client-secret: YOUR_CLIENT_SECRET
authorization-grant-type: authorization_code
redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}"
scope: openid, profile
provider:
custom:
issuer-uri: https://connect.openathens.net
Step 6: Run
(Still assuming you are running your application locally.)
Access http://localhost:8080/claims and ensure that you are able to retrieve the user claims after signing in to your OpenAthens IdP with a test account.