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

Spring Security 6:如何重写令牌验证逻辑适配非标准OIDC提供商?

Spring Security 6 适配GET类型的令牌验证URL

针对你的场景,Spring Security默认的令牌 introspection(验证)逻辑遵循标准POST请求规范,要适配GET类型的验证接口,核心是自定义OpaqueTokenIntrospector实现,替换掉默认的实现类。

步骤1:实现自定义的令牌验证器

创建一个类实现OpaqueTokenIntrospector接口,在introspect方法里发送GET请求到你的验证URL,解析响应并封装成OAuth2AuthenticatedPrincipal对象。

示例代码(用RestTemplate实现):

import org.springframework.security.oauth2.core.OAuth2AuthenticatedPrincipal;
import org.springframework.security.oauth2.server.resource.introspection.DefaultOAuth2AuthenticatedPrincipal;
import org.springframework.security.oauth2.server.resource.introspection.OpaqueTokenIntrospector;
import org.springframework.web.client.RestTemplate;
import java.util.Map;

public class GetBasedTokenIntrospector implements OpaqueTokenIntrospector {

    private final String introspectionUri;
    private final RestTemplate restTemplate;

    // 如果验证接口需要客户端认证(比如Basic Auth),可在这里注入客户端ID和密钥并配置认证
    public GetBasedTokenIntrospector(String introspectionUri) {
        this.introspectionUri = introspectionUri;
        this.restTemplate = new RestTemplate();
        // 若需Basic Auth,添加拦截器:
        // restTemplate.getInterceptors().add(new BasicAuthenticationInterceptor(clientId, clientSecret));
    }

    @Override
    public OAuth2AuthenticatedPrincipal introspect(String token) {
        // 构建带access_token参数的GET请求URL
        String url = String.format("%s?access_token=%s", this.introspectionUri, token);
        // 发送GET请求获取令牌信息
        Map<String, Object> tokenAttributes = restTemplate.getForObject(url, Map.class);
        
        // 验证令牌有效性(根据提供商返回的active字段判断)
        if (tokenAttributes == null || !Boolean.TRUE.equals(tokenAttributes.get("active"))) {
            throw new IllegalArgumentException("Invalid token");
        }
        
        // 将返回属性封装成OAuth2AuthenticatedPrincipal返回
        return new DefaultOAuth2AuthenticatedPrincipal(
                (String) tokenAttributes.get("username"),
                tokenAttributes,
                null // 权限信息,根据实际返回字段调整
        );
    }
}

步骤2:在Spring Security配置中替换默认验证器

在SecurityFilterChain配置里,指定使用自定义的OpaqueTokenIntrospector:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .authorizeHttpRequests(auth -> auth.anyRequest().authenticated())
                .oauth2ResourceServer(oauth2 -> oauth2
                        .opaqueToken(token -> token
                                .introspector(new GetBasedTokenIntrospector("https://xxxxx.domain/oauth2/rest/token/info"))
                        )
                );
        return http.build();
    }
}

关键注意事项

  • 如果验证接口需要客户端身份认证,记得在RestTemplate或WebClient中配置对应的认证逻辑(比如Basic Auth拦截器)。
  • 解析响应时,要根据提供商实际返回的字段调整,比如用户名字段可能不是username,权限信息可能在其他字段中,需对应修改DefaultOAuth2AuthenticatedPrincipal的构造参数。
  • 可添加异常处理逻辑,捕获请求超时、HTTP错误等情况,转换成Spring Security标准异常(如OAuth2AuthenticationException)。

内容的提问来源于stack exchange,提问作者François Poirier

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 15:06:07