Describe the bug
The way to configure a ReactiveOAuth2UserService<OAuth2UserRequest, OAuth2User> in OAuth2LoginSpec is inconsistent.
More specifically:
- OAuth2LoginReactiveAuthenticationManager constructor is called over getOauth2UserService() which search for a bean of type ReactiveOAuth2UserService, else fallback on DefaultReactiveOAuth2UserService
- OidcReactiveOAuth2UserService is instanciated by its default constructor, without relying on getOauth2UserService()
private ReactiveAuthenticationManager createDefault() {
[...]
OAuth2LoginReactiveAuthenticationManager oauth2Manager = new OAuth2LoginReactiveAuthenticationManager(
client, getOauth2UserService());
private ReactiveOAuth2UserService<OidcUserRequest, OidcUser> getOidcUserService() {
ResolvableType type = ResolvableType.forClassWithGenerics(ReactiveOAuth2UserService.class,
OidcUserRequest.class, OidcUser.class);
ReactiveOAuth2UserService<OidcUserRequest, OidcUser> bean = getBeanOrNull(type);
if (bean != null) {
return bean;
}
return new OidcReactiveOAuth2UserService();
}
This leads to inconsistent ReactiveOAuth2UserService through the components created by OAuth2LoginSpec.
To Reproduce
@EnableWebFluxSecurity
@Import({
CustomOAuth2UserService.class,
})
@Slf4j
@SpringBootApplication(scanBasePackages = "none")
public class InconsistentOAuth2UserDetailsServiceApp {
public static class CustomOAuth2UserService extends DefaultOAuth2UserService {
}
@Bean
public SecurityWebFilterChain configureUi(ServerHttpSecurity http) {
return http.build();
}
public static void main(String[] args) {
SpringApplication.run(InconsistentOAuth2UserDetailsServiceApp.class);
}
}
Expected behavior
Given a bean of type ReactiveOAuth2UserService, it should be injected to all components needed one, especially OidcReactiveOAuth2UserService, as it is done for OAuth2LoginReactiveAuthenticationManager
Comment From: blacelle
Workaround: provide a OidcReactiveOAuth2UserService bean with relevant ReactiveOAuth2UserService:
@Bean
public OidcReactiveOAuth2UserService oidcReactiveOAuth2UserService(
ReactiveOAuth2UserService<OAuth2UserRequest, OAuth2User> oauth2UserService) {
OidcReactiveOAuth2UserService oidcReactiveOAuth2UserService = new OidcReactiveOAuth2UserService();
oidcReactiveOAuth2UserService.setOauth2UserService(oauth2UserService);
return oidcReactiveOAuth2UserService;
}