Saturday, September 23, 2023

Integrating Azure AD with Spring Boot: A Step-by-Step Guide

  • Integrating Azure Active Directory (Azure AD) with a Java and Spring Boot application for secure authentication and authorization involves several steps. Here's a step-by-step guide along with code examples for each component. 


Step 1: Set Up Azure AD:

  • Go to Azure Active Directory.
  • Select "App registrations."
    • Click "New registration."
    • Provide a name for your application, select the supported account types (e.g., Single tenant or Multi-tenant), and specify the Redirect URI (e.g., http://localhost:8080/login/oauth2/code/azure).
    • Click "Register."
  • After registration, note down the "Application (client) ID" and "Directory (tenant) ID" for your application.
  • Under the "Certificates & secrets" tab, generate a new client secret and make sure to save it securely.

Step 2: Create a Spring Boot Application

  • Create a new Spring Boot project or use an existing one. You can use Spring Initializr or your preferred IDE to set up the project.

Step 3: Add Dependencies

  • In your pom.xml file, add the necessary dependencies for Spring Security and Azure AD integration:
    • <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-oauth2-client</artifactId> </dependency>

    Step 4: Configure Application Properties

    • In your application.properties or application.yml file, configure the Azure AD properties:
    • Replace YOUR_CLIENT_ID, YOUR_CLIENT_SECRET, and YOUR_TENANT_ID with the values from your Azure AD registration.
      • spring.security.oauth2.client.registration.azure.client-id=YOUR_CLIENT_ID spring.security.oauth2.client.registration.azure.client-secret=YOUR_CLIENT_SECRET spring.security.oauth2.client.registration.azure.redirect-uri-template={baseUrl}/login/oauth2/code/{registrationId} spring.security.oauth2.client.registration.azure.scope=openid,profile,email spring.security.oauth2.client.provider.azure.authorization-uri=https://login.microsoftonline.com/YOUR_TENANT_ID/oauth2/v2.0/authorize spring.security.oauth2.client.provider.azure.token-uri=https://login.microsoftonline.com/YOUR_TENANT_ID/oauth2/v2.0/token spring.security.oauth2.client.provider.azure.jwk-set-uri=https://login.microsoftonline.com/YOUR_TENANT_ID/discovery/v2.0/keys

      Step 5: Create a Controller

      • Create a controller to handle the authentication flow and display user information
        • import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.security.oauth2.core.user.OAuth2User; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class UserController { @GetMapping("/user") public OAuth2User user(@AuthenticationPrincipal OAuth2User principal) { return principal; } }
        • This class defines a Spring MVC controller responsible for handling incoming HTTP requests. 
        • It includes an endpoint /user that, when accessed, returns information about the authenticated user. 
        • It uses the @AuthenticationPrincipal annotation to access the user's authentication details.

        Step 6: Run the Application

        • Start your Spring Boot application:
          • ./mvnw spring-boot:run

          Step 7: Access the Application

          • Visit http://localhost:8080 in your browser, and you will be redirected to Azure AD for authentication. After successful authentication, you will be redirected back to your application.

          Step 8: Secure Endpoints

          • You can secure specific endpoints or resources by adding security configurations to your application. For example:
            • import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.oauth2.core.oidc.user.OidcUser; import org.springframework.security.oauth2.jwt.JwtDecoder; import org.springframework.security.oauth2.jwt.NimbusJwtDecoder; import org.springframework.security.oauth2.jwt.JwtValidationException; import org.springframework.security.oauth2.jwt.JwtValidators; import org.springframework.security.oauth2.jwt.NimbusReactiveJwtDecoder; import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder; import org.springframework.security.oauth2.jwt.Jwt; import org.springframework.security.oauth2.client.oidc.userinfo.OidcReactiveOAuth2UserService; import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository; import org.springframework.security.oauth2.client.registration.ClientRegistration; import org.springframework.security.oauth2.client.registration.InMemoryReactiveClientRegistrationRepository; @Configuration public class SecurityConfig { @Bean public ReactiveJwtDecoder jwtDecoder() { NimbusReactiveJwtDecoder jwtDecoder = NimbusReactiveJwtDecoder.withJwkSetUri("https://login.microsoftonline.com/YOUR_TENANT_ID/discovery/v2.0/keys") .build(); jwtDecoder.setJwtValidator(JwtValidators.createDefaultWithIssuer("https://login.microsoftonline.com/YOUR_TENANT_ID/v2.0")); return jwtDecoder; } @Bean public OidcReactiveOAuth2UserService oidcUserService() { return new OidcReactiveOAuth2UserService(); } @Bean public ReactiveClientRegistrationRepository clientRegistrationRepository() { ClientRegistration registration = ClientRegistration.withRegistrationId("azure") .clientId("YOUR_CLIENT_ID") .clientSecret("YOUR_CLIENT_SECRET") .redirectUri("{baseUrl}/login/oauth2/code/{registrationId}") .authorizationUri("https://login.microsoftonline.com/YOUR_TENANT_ID/oauth2/v2.0/authorize") .tokenUri("https://login.microsoftonline.com/YOUR_TENANT_ID/oauth2/v2.0/token") .userInfoUri("https://graph.microsoft.com/oidc/userinfo") .userNameAttributeName("email") .scope("openid", "profile", "email") .build(); return new InMemoryReactiveClientRegistrationRepository(registration); } @Bean public ReactiveJwtDecoder jwtDecoder() { return NimbusReactiveJwtDecoder.withJwkSetUri("https://login.microsoftonline.com/YOUR_TENANT_ID/discovery/v2.0/keys") .build(); } @Bean public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception { http .authorizeRequests(authorizeRequests -> authorizeRequests .antMatchers("/", "/error", "/webjars/**").permitAll() .anyRequest().authenticated() ) .oauth2Login(withDefaults()); return http.build(); } }
            • In this configuration, make sure to replace YOUR_TENANT_ID, YOUR_CLIENT_ID, and YOUR_CLIENT_SECRET with your Azure AD values.
            • this class provides configuration settings for Spring Security. It includes the following components:
              • ReactiveJwtDecoder jwtDecoder(): Configures a JWT (JSON Web Token) decoder that validates JWTs issued by Azure AD. It specifies the JWK (JSON Web Key) Set URI for Azure AD's public keys and sets up JWT validation.
              • OidcReactiveOAuth2UserService oidcUserService(): Configures the OAuth2 user service for handling OpenID Connect-specific details, such as user attributes.
              • ReactiveClientRegistrationRepository clientRegistrationRepository(): Configures the Azure AD client registration details, including the client ID and client secret. It specifies the authorization and token URIs, as well as the user info URI for Azure AD.
              • SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http): Defines the security filter chain, specifying the authorization rules for different endpoints. In this example, it permits access to /, /error, and /webjars/** without authentication, but it requires authentication for all other endpoints.
            • With these steps and configurations, your Spring Boot application is integrated with Azure AD for secure authentication and authorization. Users will be able to log in using their Azure AD credentials, and you can secure specific endpoints as needed.

            Azure AD Advantages and Disadvantages

            Advantages
            • Enables users to sign in using usernames and passwords that are used elsewhere
            • Creating and maintaining user accounts is no longer needed
            • Computer policies can be created to automatically update and secure workstations
            • Sharing resources such as files and printers is easier all users have access to set permissions
            • No longer need to provide a username and password for Outlook emails
            • It is more secure than other directory services (Login Authentication)
            • It is easy to manage, administrate and control
            • Increased scalability
            • The speed at which it is able to provide domain names
            • Simple identity management as you can view all user information
            • Let’s you manage your network from one point
            • It is also easy to set up and use
            Disadvantages
            • It can be expensive as you will need Windows Server 2000 licenses and you may need to upgrade the hardware on the server so it can run Windows Server 2000
            • Active directory is OS-dependent
            • High maintenance cost
            • If the Active Directory goes down so does your network
            • If it is set up wrong it can take time and money to remove it and set it up again
            • It is prone to be hacked
            • The cost of the infrastructure can be high
            • You need to have good planning to set it up properly
            • It also has a complex infrastructure for the user

            What is Identity Providers (IdPs)

            You may also like

            Kubernetes Microservices
            Python AI/ML
            Spring Framework Spring Boot
            Core Java Java Coding Question
            Maven AWS