How to create a OAuth and OpenID Connect (OIDC) Authentication in Spring Boot

OAuth and OpenID Connect authentication module in Spring Boot using the Spring Security and Spring Security OAuth2 libraries:

Step 1: Add dependencies Add the following dependencies to your Maven pom.xml file:

				
					<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
				
			

Step 2: Configure application properties In your application.properties file, configure the OAuth 2.0 client properties for the provider you want to use. Here’s an example for Google as the provider:

				
					spring.security.oauth2.client.registration.google.client-id=your-client-id
spring.security.oauth2.client.registration.google.client-secret=your-client-secret
spring.security.oauth2.client.registration.google.redirect-uri=http://localhost:8080/login/oauth2/code/google
spring.security.oauth2.client.registration.google.scope=openid,email,profile
spring.security.oauth2.client.provider.google.issuer-uri=https://accounts.google.com
				
			

Step 3: Create the OAuth 2.0 and OpenID Connect authentication module Create a class called OAuth2AuthModule with the following contents:

				
					import org.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
import org.springframework.security.oauth2.client.annotation.RegisteredOAuth2AuthorizedClient;
import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
import org.springframework.security.oauth2.core.oidc.user.OidcUser;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@EnableWebSecurity
@EnableOAuth2Sso
public class OAuth2AuthModule {

    private final ClientRegistrationRepository clientRegistrationRepository;

    public OAuth2AuthModule(ClientRegistrationRepository clientRegistrationRepository) {
        this.clientRegistrationRepository = clientRegistrationRepository;
    }

    @GetMapping("/userinfo")
    public OidcUser userInfo(@RegisteredOAuth2AuthorizedClient("google") OAuth2AuthorizedClient authorizedClient) {
        return (OidcUser) authorizedClient.getPrincipal();
    }

    @GetMapping("/oauth2/authorization/google")
    public String getAuthorizationEndpoint() {
        ClientRegistration registration = clientRegistrationRepository.findByRegistrationId("google");
        return "redirect:" + registration.getProviderDetails().getAuthorizationUri();
    }
}
				
			

In this example, the OAuth2AuthModule class is annotated with @EnableWebSecurity to enable Spring Security and @EnableOAuth2Sso to enable OAuth 2.0 Single Sign-On (SSO). The /userinfo endpoint retrieves the user information from the authorized client, and the /oauth2/authorization/google endpoint redirects the user to the Google authorization endpoint.

Step 4: Create a controller to handle the callback from the OAuth provider Create a class called OAuth2LoginCallbackController to handle the callback from the OAuth provider. This controller will receive the authorization code, exchange it for an access token, and authenticate the user. Here’s an example:

				
					import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class OAuth2LoginCallbackController {

    @GetMapping("/login/oauth2/code/google")
    public String handleGoogleCallback(@RequestParam("code") String code, Authentication authentication) {
        // Handle the OAuth provider callback
        // Exchange the authorization code for an access token
        // Authenticate the user
        
        // Redirect the user to the desired endpoint
        return "redirect:/home";
    }
}
				
			

In this example, the handleGoogleCallback method handles the callback from the Google OAuth provider. You can customize this method to perform the necessary steps to exchange the authorization code for an access token, authenticate the user, and redirect them to the desired endpoint.

Step 5: Customize the OAuth 2.0 provider configuration If you want to use an OAuth 2.0 provider other than Google, you can customize the provider configuration. Create a class called OAuth2ProviderConfig and implement the ClientRegistrationRepository interface. Here’s an example for Google as the provider:

				
					import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
import org.springframework.stereotype.Component;

@Component
public class OAuth2ProviderConfig implements ClientRegistrationRepository {

    private final ClientRegistration googleClientRegistration;

    public OAuth2ProviderConfig() {
        this.googleClientRegistration = CustomOAuthProviderBuilder.google().build();
    }

    @Override
    public ClientRegistration findByRegistrationId(String registrationId) {
        if (registrationId.equals("google")) {
            return googleClientRegistration;
        }
        return null;
    }
}
				
			

In this example, the OAuth2ProviderConfig class implements the ClientRegistrationRepository interface and provides the Google client registration.

Please note that this is a basic example, and you may need to customize it further based on your specific requirements, such as handling token storage, integrating with a user database, and configuring additional OAuth 2.0 providers.