Search code examples
spring-bootspring-securityspring-oauth2

How to disable Spring (Boot) Security OAuth based on a config profile or specific property?


I'm integrating OAuth2 (Google as the OIDC provider) into an existing Spring Boot app that currently uses a simple DaoAuthenticationProvider. I've made the changes to get OAuth integration to work, but now I need to provide a configuration switch to turn it off in certain environments (fall back to using the old database-based authentication).

The configuration to use OAuth2 looks like this:

spring:
  security:
    oauth2:
      client:
        registration:
          google:
            client-id: 1234567890-1a2b3c4d5e6f7g8h9i0j.apps.googleusercontent.com
            client-secret: ABCDEF-1234-OU812_XYZZY

My @Configuration class for authentication looks like this:

@Configuration
@EnableWebSecurity
public class GoogleOIDCSecurityConfiguration {

    @Bean
    OidcUserService oidcUserService() {
        Set<String> scopes = Set.of(
                "https://www.googleapis.com/auth/userinfo.email",
                "https://www.googleapis.com/auth/userinfo.profile"
                );
        OidcUserService service = new OidcUserService();
        service.setAccessibleScopes(scopes);
        return service;
    }

    @Bean
    SecurityFilterChain oidcFilterChain(HttpSecurity http, OidcUserService userService) throws Exception {
        http
            .authorizeHttpRequests(this::configureAuthorization)
            .oauth2Login(c -> configureOAuth2(c, userService))
            .logout(this::configureLogout)
            ;

        return http.build();
    }

    protected void configureAuthorization(AuthorizeHttpRequestsConfigurer<HttpSecurity>.AuthorizationManagerRequestMatcherRegistry authorize) {
        authorize
            .dispatcherTypeMatchers(DispatcherType.FORWARD, DispatcherType.INCLUDE, DispatcherType.ERROR).permitAll()

            .requestMatchers("/*/*.js", "/*/*/*.js", "/css/**", "/lib/**", "/assets/**", "favicon.ico").permitAll()
            .requestMatchers("/", LOGIN_PAGE, INVALID_SESSION_PAGE, LOGOUT_PAGE).permitAll()
            .requestMatchers("/foo/**").hasAnyRole(Roles.FOO)
            .requestMatchers("/admin/**").hasRole(Roles.ADMIN)
            .anyRequest().authenticated();
    }

    private void configureOAuth2(OAuth2LoginConfigurer<HttpSecurity> oauthLogin, OidcUserService userService) {
        oauthLogin
            .userInfoEndpoint(endpoint -> endpoint.oidcUserService(userService));
    }
}

My first attempt at disabling it conditionally was to set client-id to empty in certain profiles and use @ConditionalOnProperty referencing that key. That fails with a validation exception saying client-id can not be empty. It seems that having anything under spring.security.oauth2.client.registration.* triggers auto-config of OAuth.

What I need to do is find a way to completely disable the auto-configuration for any OAuth clients, but only in certain profiles (or using a specific config property).


Solution

  • Why don't you put all of your OAuth2 configuration properties and beans into that profile?

    # properties for all profiles here
    
    ---
    spring:
      config:
        activate:
          on-profile:
          - oauth2
      security:
        oauth2:
          client:
            registration:
              google:
                client-id: 1234567890-1a2b3c4d5e6f7g8h9i0j.apps.googleusercontent.com
                client-secret: ABCDEF-1234-OU812_XYZZY
    
    @Profile("oauth2")
    @Configuration
    @EnableWebSecurity
    public class GoogleOIDCSecurityConfiguration {
        ...
    }
    
    @Profile("legacy")
    @Configuration
    @EnableWebSecurity
    public class LegacySecurityConfiguration {
        ...
    }