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.