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

Spring Boot微服务Spring Security OIDC/OAuth2代理下Issuer不匹配求助

解决Spring Security JWT Issuer不匹配问题

你的问题核心是网关/代理导致客户端访问的授权服务器地址与令牌中的issuer不一致,Spring Security默认会严格校验issuer的匹配性,因此抛出异常。以下是几种可行的解决方案:

方案1:配置Issuer映射(Spring Boot 2.6+ 推荐)

如果使用Spring Boot 2.6及以上版本,可以直接通过配置文件将实际返回的issuer映射为客户端配置的地址,无需修改代码:

在application.yml中添加:

spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: https://clidens1.aqp.it:9443/oauth2/token
          issuer-mapping:
            https://ids-for-spid.aqp.it/oauth2/token: https://clidens1.aqp.it:9443/oauth2/token

该配置会让Spring Security将令牌中的https://ids-for-spid.aqp.it/oauth2/token视为与配置的issuer等价,直接通过校验。

方案2:自定义JWT解码器(适配旧版本)

对于Spring Boot 2.6以下版本,或者需要更灵活的校验逻辑,可以自定义JwtDecoder来处理issuer的匹配:

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Value("${spring.security.oauth2.resourceserver.jwt.issuer-uri}")
    private String configuredIssuer;

    @Bean
    public JwtDecoder jwtDecoder() {
        // 基于配置的issuer创建默认解码器
        NimbusJwtDecoder decoder = NimbusJwtDecoder.withJwkSetUri(configuredIssuer + "/.well-known/jwks.json").build();
        
        // 替换默认的JWT校验逻辑,处理issuer映射
        decoder.setJwtValidator(jwt -> {
            String tokenIssuer = jwt.getIssuer();
            // 匹配实际返回的issuer,替换为配置的地址
            if ("https://ids-for-spid.aqp.it/oauth2/token".equals(tokenIssuer)) {
                // 构造新的JWT对象,将issuer替换为配置值
                Jwt adjustedJwt = Jwt.withTokenValue(jwt.getTokenValue())
                        .headers(jwt.getHeaders())
                        .claims(claims -> claims.putAll(jwt.getClaims()))
                        .issuer(configuredIssuer)
                        .build();
                // 返回校验通过的结果
                return JwtValidatorResult.success(adjustedJwt);
            }
            // 其他情况沿用默认校验逻辑
            return JwtValidatorResult.success();
        });
        
        return decoder;
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth.anyRequest().authenticated())
            .oauth2ResourceServer(oauth2 -> oauth2.jwt(jwt -> jwt.decoder(jwtDecoder())));
        return http.build();
    }
}

方案3:修改授权服务器的Issuer配置(根源解决)

如果有权限修改授权服务器(如Spring Authorization Server、Keycloak等),直接将授权服务器的issuer配置为代理后的访问地址https://clidens1.aqp.it:9443/oauth2/token,这样well-known配置返回的issuer会与客户端访问地址完全一致,从根源避免该问题。

以Spring Authorization Server为例,配置ProviderSettings:

@Bean
public ProviderSettings providerSettings() {
    return ProviderSettings.builder()
            .issuer("https://clidens1.aqp.it:9443/oauth2/token")
            .build();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 20:25:49