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

Spring Boot资源服务器报错:JOSE header typ(JOSE)不被允许

问题:Spring Boot资源服务器拒绝公司授权服务器的ID Token,提示JOSE头部typ不允许

问题背景

  • 架构:Spring Boot OAuth客户端 + Angular前端 + Spring Boot资源服务器
  • 认证流程:Angular发起OAuth认证 → 重定向至公司授权服务器 → 授权完成后携带code返回Angular → Angular将code传给Spring Boot客户端 → 客户端返回access token、ID token等凭证
  • 异常表现:对接Google授权服务器时,用ID Token作为Bearer Token访问资源服务器正常;但使用公司授权服务器的Token访问时,返回未授权响应,错误信息:

Bearer error="invalid_token", error_description="An error occurred while attempting to decode the Jwt: JOSE header typ (type) JOSE not allowed"

  • 资源服务器日志:
o.s.s.o.s.r.a.JwtAuthenticationProvider [ajp-nio-8009-exec-399] Failed to authenticate since the JWT was invalid

排查结论

问题根源在于公司授权服务器返回的ID Token头部typ字段值为JOSE,而非标准的JWT:

{
  "alg": "RS256",
  "typ": "JOSE"
}

当前配置

资源服务器配置类

@Configuration
public class ResourceServerConfig 
{
    @Value("${spring.security.oauth2.resourceserver.jwt.issuer-uri}")
    private String issuerUri;
    
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception 
    {
        http.csrf().disable()
        .authorizeRequests(authorizeRequests -> authorizeRequests
            .anyRequest().authenticated())
        .oauth2ResourceServer(oauth2 -> oauth2
                .jwt(Customizer.withDefaults()));
        
        return http.build();
    }
}

应用配置属性

spring.security.oauth2.resourceserver.jwt.issuer-uri={COMPANY_AUTH}
spring.security.oauth2.resourceserver.jwt.jwk-set-uri={COMPANY_AUTH}/jwk

注:{COMPANY_AUTH}与ID Token中的iss字段一致,使用Spring Boot v2.6.7。

解决方案

Spring Security默认仅允许JWT头部typ字段值为JWT或不指定,要兼容JOSE值,需自定义JWT解码器,放宽typ字段的校验逻辑:

方案1:允许JOSE和JWT两种typ值

修改资源服务器配置类,自定义JwtDecoder Bean:

@Configuration
public class ResourceServerConfig 
{
    @Value("${spring.security.oauth2.resourceserver.jwt.issuer-uri}")
    private String issuerUri;
    
    @Bean
    public JwtDecoder jwtDecoder() {
        return NimbusJwtDecoder.withIssuerLocation(issuerUri)
                .jwtProcessorCustomizer(jwtProcessor -> {
                    ConfigurableJWTProcessor<SecurityContext> processor = 
                            (ConfigurableJWTProcessor<SecurityContext>) jwtProcessor;
                    processor.setJWSTypeVerifier(new DefaultJOSEObjectTypeVerifier<>() {
                        @Override
                        public void verify(final JOSEObjectType type, final SecurityContext context)
                                throws BadJOSEException {
                            // 允许typ为JOSE或JWT
                            if (!JOSEObjectType.JWT.equals(type) && !new JOSEObjectType("JOSE").equals(type)) {
                                throw new BadJOSEException("Unsupported JWT type: " + type);
                            }
                        }
                    });
                })
                .build();
    }
    
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception 
    {
        http.csrf().disable()
        .authorizeRequests(authorizeRequests -> authorizeRequests
            .anyRequest().authenticated())
        .oauth2ResourceServer(oauth2 -> oauth2
                .jwt(jwt -> jwt.decoder(jwtDecoder())));
        
        return http.build();
    }
}

方案2:完全跳过typ字段校验

如果不需要校验typ字段,可直接放行:

@Bean
public JwtDecoder jwtDecoder() {
    return NimbusJwtDecoder.withIssuerLocation(issuerUri)
            .jwtProcessorCustomizer(jwtProcessor -> {
                ConfigurableJWTProcessor<SecurityContext> processor = 
                        (ConfigurableJWTProcessor<SecurityContext>) jwtProcessor;
                processor.setJWSTypeVerifier((type, context) -> {
                    // 不做任何typ校验
                });
            })
            .build();
}

说明

Spring Security底层依赖Nimbus库处理JWT,默认的DefaultJOSEObjectTypeVerifier仅允许typ为JWT,上述配置通过自定义校验逻辑实现对JOSE值的兼容,适配Spring Boot 2.6.7对应的Spring Security 5.6.x版本。

内容的提问来源于stack exchange,提问作者Thomas A Mathew

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 21:40:11