You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Authorization Server无法添加OAuth2授权码请求认证提供者

问题解决:让OAuth2AuthorizationCodeRequestAuthenticationProvider加入AuthenticationManager

你的核心问题是手动指定全局AuthenticationManager覆盖了Spring Authorization Server自动构建的专用AuthenticationManager,导致OAuth2专属认证提供者未被注入到授权请求的过滤器链中。以下是具体修复方案:

1. 移除全局AuthenticationManager的手动绑定

在oauthFilterChain配置中删除这一行:

.authenticationManager(authenticationManager)

Spring Authorization Server的OAuth2AuthorizationServerConfigurer会自动为授权端点、令牌端点创建包含所需认证提供者的专用AuthenticationManager,手动传入全局管理器会覆盖该逻辑,导致OAuth相关Provider丢失。

2. 修正OAuth2AuthorizationCodeRequestAuthenticationProvider的配置位置

你之前错误地将该Provider同时添加到clientAuthentication和authorizationEndpoint中,clientAuthentication有专属的认证提供者(如OAuth2ClientAuthenticationProvider),无需添加授权码请求的Provider。仅在authorizationEndpoint下配置即可:

authorizationServerConfigurer
    .registeredClientRepository(registeredClientRepository) 
    .tokenGenerator(tokenGenerator) 
    .authorizationEndpoint(authorizationEndpoint -> authorizationEndpoint
            .authenticationProvider(authorizationCodeRequestAuthenticationProvider)
    )    
    .tokenEndpoint(tokenEndpoint -> { })    
;

3. 保留全局认证逻辑的说明

如果全局AuthenticationManager中的DaoAuthenticationProvider等需要生效,无需手动绑定整个管理器。Spring Security过滤器链会自动用全局认证管理器处理表单登录等上游认证,授权端点则使用Authorization Server创建的专用管理器处理OAuth2相关请求,两者互不冲突。

完整修正后的oauthFilterChain代码示例

@Bean
@Order(103)
public SecurityFilterChain oauthFilterChain(HttpSecurity http, 
                                            JdbcRegisteredClientRepository registeredClientRepository,
                                            OAuth2TokenGenerator<?> tokenGenerator,
                                            OAuth2AuthorizationCodeRequestAuthenticationProvider authorizationCodeRequestAuthenticationProvider) 
                            throws Exception
{
    http
        .securityMatcher("/oauth/**")
        .authorizeHttpRequests(auth -> auth
            .requestMatchers("/oauth/authorize").hasRole("MEMBER")
            .requestMatchers("/oauth/**").permitAll()
        )
        .sessionManagement(session -> session
            .sessionCreationPolicy(SessionCreationPolicy.ALWAYS)
            .sessionFixation(c -> c.none())  // FIXME turn it back on 
        )
        // 移除全局AuthenticationManager绑定
        .formLogin(form -> form
            .successForwardUrl("/oauth/authorize")
            .loginProcessingUrl("/oauth/do_login")
            .failureUrl("/oauth/login?failure=true")
            .successHandler(oauthAuthenticationSuccessHandler())
            .usernameParameter("username")
            .passwordParameter("password")
            .loginPage(OAUTH_LOGIN_VIEW_NAME)
        )
        .exceptionHandling(exception -> exception.authenticationEntryPoint(oauthLoginEntryPoint()))
        .csrf(withDefaults())
        ;
    
    OAuth2AuthorizationServerConfigurer authorizationServerConfigurer = new OAuth2AuthorizationServerConfigurer();
    http.apply(authorizationServerConfigurer);
    authorizationServerConfigurer
        .registeredClientRepository(registeredClientRepository) 
        .tokenGenerator(tokenGenerator) 
        .authorizationEndpoint(authorizationEndpoint -> authorizationEndpoint
                .authenticationProvider(authorizationCodeRequestAuthenticationProvider)
        )    
        .tokenEndpoint(tokenEndpoint -> { })    
    ;
   
    return http.build();
    
}

验证方式

重启应用后,断点调试OAuth2AuthorizationEndpointFilter的doFilterInternal方法,查看AuthenticationManager的providers列表,即可确认OAuth2AuthorizationCodeRequestAuthenticationProvider已被包含。

内容的提问来源于stack exchange,提问作者Ken DeLong

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 09:57:01