Skip to main content
Skip table of contents

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.

  • This is sample code and is not production ready

  • Proper error handling is not implemented

  • Authorization is not implemented. This example shows how to obtain the claims necessary to authorize visiting users

  • You will need to configure your application.properties with the details for an application that you will create with the Service Provider dashboard - https://sp.openathens.net

Step 1: Initialize the project

This example uses Spring Boot and its 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 or application.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.

JAVA
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 organization and should be authorized.

JAVA
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: Create an application in the Service Provider Dashboard

  1. Access the Service Provider dashboard: https://sp.openathens.net/.

  2. Create a new OIDC application.

  3. In the configuration tab of the OIDC application you created, 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.)

  4. 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 Service Provider dashboard to configure your OIDC client. You may need to rename the default config file from “.properties” to “.yml” though.

YAML
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.

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.