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

Spring Boot资源服务器(5.7及更早版本)替换BearerTokenAuthentication方法

Spring Security 5.7及更早版本替换不透明令牌认证后的Authentication实例

在Spring Security 5.7及更早版本中,要将不透明令牌 introspection 生成的BearerTokenAuthentication替换为自定义Authentication实现,可通过以下两种方式实现:

方案一:自定义OpaqueTokenAuthenticationProvider

核心思路是重写默认的OpaqueTokenAuthenticationProvider,在认证流程的最后阶段替换生成的认证对象:

  1. 实现自定义Authentication类
    先定义你的自定义认证对象,比如CustomAuthentication,需实现Authentication接口或继承AbstractAuthenticationToken:
public class CustomAuthentication extends AbstractAuthenticationToken {
    private final String token;
    private final Object principal;

    public CustomAuthentication(Object principal, Collection<? extends GrantedAuthority> authorities, String token) {
        super(authorities);
        this.principal = principal;
        this.token = token;
        setAuthenticated(true);
    }

    @Override
    public Object getCredentials() {
        return this.token;
    }

    @Override
    public Object getPrincipal() {
        return this.principal;
    }
}
  1. 自定义OpaqueTokenAuthenticationProvider
    继承默认的OpaqueTokenAuthenticationProvider,重写authenticate方法,在原认证逻辑完成后,将BearerTokenAuthentication转换为自定义的认证对象:
public class CustomOpaqueTokenAuthenticationProvider extends OpaqueTokenAuthenticationProvider {

    public CustomOpaqueTokenAuthenticationProvider(OpaqueTokenIntrospector introspector) {
        super(introspector);
    }

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        // 先执行默认的令牌校验与解析逻辑
        Authentication defaultAuth = super.authenticate(authentication);
        if (defaultAuth instanceof BearerTokenAuthentication bearerAuth) {
            // 转换为自定义Authentication实例
            return new CustomAuthentication(
                bearerAuth.getPrincipal(),
                bearerAuth.getAuthorities(),
                bearerAuth.getToken()
            );
        }
        return defaultAuth;
    }
}
  1. 配置SecurityFilterChain
    在Spring Security配置中,替换默认的OpaqueTokenAuthenticationProvider为自定义实现:
@Configuration
@EnableWebSecurity
public class ResourceServerConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth.anyRequest().authenticated())
            .oauth2ResourceServer(oauth2 -> oauth2
                .opaqueToken(token -> token
                    .authenticationProvider(customOpaqueTokenAuthenticationProvider())
                )
            );
        return http.build();
    }

    @Bean
    public CustomOpaqueTokenAuthenticationProvider customOpaqueTokenAuthenticationProvider() {
        // 这里可以使用默认的NimbusOpaqueTokenIntrospector,或者自定义的Introspector
        OpaqueTokenIntrospector introspector = new NimbusOpaqueTokenIntrospector(
            "https://your-auth-server/introspect",
            "your-client-id",
            "your-client-secret"
        );
        return new CustomOpaqueTokenAuthenticationProvider(introspector);
    }
}

方案二:通过AuthenticationPostProcessor处理

如果不想重写整个Provider,也可以通过在认证流程后添加一个AuthenticationPostProcessor,将BearerTokenAuthentication转换为自定义实例:

  1. 自定义AuthenticationPostProcessor
public class CustomAuthenticationPostProcessor implements AuthenticationPostProcessor {
    @Override
    public Authentication postProcess(Authentication authentication) {
        if (authentication instanceof BearerTokenAuthentication bearerAuth) {
            return new CustomAuthentication(
                bearerAuth.getPrincipal(),
                bearerAuth.getAuthorities(),
                bearerAuth.getToken()
            );
        }
        return authentication;
    }
}
  1. 配置到BearerTokenAuthenticationFilter
    在Security配置中,获取BearerTokenAuthenticationFilter并设置自定义的AuthenticationPostProcessor:
@Configuration
@EnableWebSecurity
public class ResourceServerConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth.anyRequest().authenticated())
            .oauth2ResourceServer(oauth2 -> oauth2.opaqueToken(Customizer.withDefaults()));

        // 获取BearerTokenAuthenticationFilter并设置PostProcessor
        http.addFilterAfter(
            new BearerTokenAuthenticationFilter(
                http.getSharedObject(AuthenticationManager.class),
                new BearerTokenAuthenticationConverter()
            ) {
                @Override
                protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
                    Authentication customAuth = new CustomAuthenticationPostProcessor().postProcess(authResult);
                    super.successfulAuthentication(request, response, chain, customAuth);
                }
            },
            BearerTokenAuthenticationFilter.class
        );

        return http.build();
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 20:37:50