Using Spring Security 5 OAuth2 Client Support disables Spring Boot Actuator Basic Authentication

Viewed 269

I am using Spring Boot 2.4.0 and Spring Cloud 2020.0.0-M6

I just migrated the OAuth clients in my codebase from using Spring Security OAuth to using Spring Security 5's OAuth support (following https://github.com/spring-projects/spring-security/wiki/OAuth-2.0-Migration-Guide)

I got all of my clients to successfully retrieve tokens and send them along to downstream services appropriately. However once I got this to work, I noticed that I could no longer access any of my Spring Boot Actuator endpoints which had been protected by Basic Authentication.

After debugging, I discovered that the reason is because in

org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration

the instantiation of the InMemoryUserDetailsManager is gated by the existence of the ClientRegistrationRespository

@Bean
@ConditionalOnMissingBean(type = "org.springframework.security.oauth2.client.registration.ClientRegistrationRepository")
@Lazy
public InMemoryUserDetailsManager inMemoryUserDetailsManager(SecurityProperties properties,

I was able to work around this problem by explicitly building the inMemoryUserDetailsManager bean myself (by copying the code from UserDetailsServiceAutoConfiguration and not gating it) but that seems inappropriate.

I do not know if this is a bug with the configuration or not. Should something else be checked to decide if we should instantiate the InMemoryUserDetailsManager? It seems completely reasonable to use OAuth2 for calling downstream services while having actuator endpoints protected by Basic Authentication. I could be missing something, or my understanding of the downstream oauth configuration could be wrong.

The only oauth configuration I have is this:

spring.security.oauth2.client.provider.my-oauth-provider.token-uri=${ouath-provider-url-property}/token

spring.security.oauth2.client.registration.my-client.client-id=${client-id-property}
spring.security.oauth2.client.registration.my-client.client-secret=${client-secret-property}
spring.security.oauth2.client.registration.my-client.provider=my-oauth-provider
spring.security.oauth2.client.registration.my-client.authorization-grant-type=client_credentials
spring.security.oauth2.client.registration.my-client.scope=RETURN_ALL_CLIENT_SCOPES
spring.security.oauth2.client.registration.my-client.client-authentication-method=POST

The actuator security configuration I have is this:

@Configuration
@EnableWebSecurity
public class ActuatorSecurity extends WebSecurityConfigurerAdapter {

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.csrf()
        .disable()
        .authorizeRequests()
        .requestMatchers(
            EndpointRequest.to(
                "health",
                "env",
                "jolokia",
                "circuitbreakers",
                "metrics",
                "beans",
                "configprops",
                "mappings",
                "httptrace",
                "caches",
                "cache-keys",
                "loggers"))
        .authenticated()
        .and()
        .httpBasic();
  }
}

spring.security.user.name=username
spring.security.user.password=password

Any help is appreciated, as I would like to be able to configure some flag that allows me to instantiate the basic authentication without having to hand-code it myself.

0 Answers
Related