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

Spring Security OAuth2资源服务器InvalidBearerTokenException问题咨询

问题分析与解决办法

你的核心问题很明确:Spring Boot资源服务器配置成了JWT解析模式,但Keycloak返回的是UUID格式的不透明Bearer令牌,不是标准JWT,所以Spring Security尝试解析JWT时直接抛出Malformed token异常。

下面针对你的两个问题逐一说明:

问题1:是否可以告知资源服务器该token是普通Bearer Token而非IdToken?

首先纠正一个概念:你拿到的不是IdToken,是不透明令牌(Opaque Token)——这类令牌是一串无意义的字符串,无法本地解析,必须调用授权服务器(Keycloak)的令牌校验接口(introspect)来验证有效性并获取令牌信息。

所以不是“告知资源服务器不是IdToken”,而是要把资源服务器的配置从JWT模式切换到不透明令牌模式。修改你的SecurityFilterChain配置,把oauth2ResourceServer.jwt()换成oauth2ResourceServer.opaqueToken(),同时配置Keycloak的令牌校验端点和资源服务器自身的客户端凭证(资源服务器需要用这些信息去Keycloak验证令牌)。

修改后的配置示例:

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
            .csrf(AbstractHttpConfigurer::disable)
            .authorizeHttpRequests(authz -> authz.anyRequest().permitAll())
            .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
            .oauth2ResourceServer(oauth2 -> oauth2
                    .opaqueToken(opaque -> opaque
                            // 配置Keycloak令牌校验端点与资源服务器客户端信息
                            .introspectionUri("http://your-keycloak-host/auth/realms/your-realm/protocol/openid-connect/token/introspect")
                            .clientId("your-resource-server-client-id")
                            .clientSecret("your-resource-server-client-secret")
                    )
                    .authenticationEntryPoint((request, response, exception) -> {
                        System.out.println("Authentication failed");
                        BearerTokenAuthenticationEntryPoint delegate = new BearerTokenAuthenticationEntryPoint();
                        delegate.commence(request, response, exception);
                    })
            );
    return http.build();
}

也可以把配置参数放到application.properties中,避免硬编码:

spring.security.oauth2.resourceserver.opaquetoken.introspection-uri=http://your-keycloak-host/auth/realms/your-realm/protocol/openid-connect/token/introspect
spring.security.oauth2.resourceserver.opaquetoken.client-id=your-resource-server-client-id
spring.security.oauth2.resourceserver.opaquetoken.client-secret=your-resource-server-client-secret

问题2:将客户端设置为bearer-only能否解决该异常?

不能直接解决,但这是Keycloak端的必要配置。

Keycloak里的bearer-only客户端类型,是用来标记这个客户端只能作为资源服务器接收令牌,不能主动发起授权请求去获取令牌——这是资源服务器客户端的标准配置,但它不会改变Keycloak返回的令牌格式。

你现在的问题是资源服务器解析令牌的方式和令牌格式不匹配,所以哪怕把客户端设为bearer-only,只要资源服务器还是用JWT模式解析,依然会报错。

正确的流程是:

  1. 在Keycloak中将资源服务器对应的客户端设置为bearer-only(最佳实践,避免该客户端被误用)
  2. 同时把Spring Security的资源服务器配置改成不透明令牌模式(参考问题1的配置)

这样才能彻底解决Malformed token的异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 11:19:52