Spring Security 5.7.11中如何禁用OAuth2LoginAuthenticationProvider
解决Spring Security 5.7.x中禁用默认OAuth2LoginAuthenticationProvider的问题
在Spring Boot迁移过程中,从Spring Security 5.3.9.RELEASE升级至5.7.11时,自定义的OIDCAuthorizationCodeAuthenticationProvider始终排在AuthenticationProvider列表末尾,导致系统优先使用内置的OAuth2LoginAuthenticationProvider,进而引发后续流程异常。当前提供者列表如下:
- AnonymousAuthenticationProvider
- OAuth2LoginAuthenticationProvider
- OIDCAuthorizationCodeAuthenticationProvider
问题根源在于ProviderManager的authenticate方法会按顺序遍历所有提供者,找到第一个支持当前Authentication类型的实例后,就会调用其认证逻辑,一旦返回非null结果就直接终止遍历,不会继续执行后续提供者的逻辑。
方法一:直接移除默认的OAuth2LoginAuthenticationProvider
通过自定义SecurityFilterChain,获取AuthenticationManagerBuilder并移除默认的OAuth2LoginAuthenticationProvider实例:
@Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .oauth2Login(oauth2 -> oauth2 // 此处配置你的OIDC相关参数 ) .authenticationManager(authenticationManager(http)); return http.build(); } private AuthenticationManager authenticationManager(HttpSecurity http) throws Exception { AuthenticationManagerBuilder authBuilder = http.getSharedObject(AuthenticationManagerBuilder.class); // 注册自定义的认证提供者 authBuilder.authenticationProvider(new OIDCAuthorizationCodeAuthenticationProvider()); // 移除默认的OAuth2LoginAuthenticationProvider List<AuthenticationProvider> providers = authBuilder.getObject().getProviders(); providers.removeIf(provider -> provider instanceof OAuth2LoginAuthenticationProvider); return authBuilder.build(); }
方法二:调整自定义Provider的执行优先级(替代方案)
如果需要保留默认提供者但优先使用自定义逻辑,可以让自定义Provider实现Ordered接口,设置比OAuth2LoginAuthenticationProvider更高的优先级:
public class OIDCAuthorizationCodeAuthenticationProvider implements AuthenticationProvider, Ordered { @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { // 自定义认证逻辑实现 } @Override public boolean supports(Class<?> authentication) { // 确保支持目标Authentication类型,例如OAuth2AuthorizationCodeAuthenticationToken return OAuth2AuthorizationCodeAuthenticationToken.class.isAssignableFrom(authentication); } @Override public int getOrder() { // 设置优先级高于默认的OAuth2LoginAuthenticationProvider(默认优先级为Ordered.LOWEST_PRECEDENCE - 10) return Ordered.LOWEST_PRECEDENCE - 20; } }
两种方案对比:
- 方法一彻底移除默认提供者,从根源上避免冲突,适合不需要默认OAuth2登录逻辑的场景;
- 方法二通过调整执行顺序让自定义逻辑优先执行,适合需要保留默认逻辑作为 fallback 的场景。
内容的提问来源于stack exchange,提问作者Andreas
相关产品推荐
相关产品推荐

