Spring OAuth2中能否修改或移除JWT默认声明?
当然可以搞定!其实Spring OAuth2并没有把这些默认声明焊死,我们完全可以修改甚至移除它们——哪怕你不想用TokenEnhancer加新声明,也能靠它来做「减法」或者「修改」。下面给你分享两种实操性强的方案:
方案1:用TokenEnhancer直接修改/删除已有声明
虽然大家常说TokenEnhancer是用来加自定义声明的,但它本质上是拿到已生成的令牌对象,对里面的claims做二次处理。所以我们可以直接在这个环节删掉不需要的默认字段,或者修改它们的值。
比如写一个自定义的Enhancer:
@Component public class CustomJwtClaimsModifier implements TokenEnhancer { @Override public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) { if (accessToken instanceof JwtAccessToken) { JwtAccessToken jwtToken = (JwtAccessToken) accessToken; Map<String, Object> claims = jwtToken.getJwtClaims(); // 移除你不需要的默认声明 claims.remove("client_id"); claims.remove("jti"); // 如果要修改过期时间,注意要符合JWT的时间戳格式(秒级) // claims.put("exp", System.currentTimeMillis() / 1000 + 7200); // 比如改成2小时过期 } return accessToken; } }
然后把这个Enhancer配置到授权服务器的端点链里:
@Configuration @EnableAuthorizationServer public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { @Autowired private CustomJwtClaimsModifier claimsModifier; @Autowired private JwtAccessTokenConverter jwtAccessTokenConverter; @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { TokenEnhancerChain enhancerChain = new TokenEnhancerChain(); // 注意顺序:先执行我们的修改器,再执行转换器 enhancerChain.setTokenEnhancers(Arrays.asList(claimsModifier, jwtAccessTokenConverter)); endpoints.tokenEnhancer(enhancerChain); } }
方案2:自定义JwtAccessTokenConverter从根源控制声明
如果想在生成JWT的更早阶段就过滤掉不需要的声明,可以自定义JwtAccessTokenConverter,重写它的convertAccessToken方法——这个方法是用来把OAuth2AccessToken转换成JWT claims的核心逻辑,在这里修改的话更彻底。
示例代码:
public class CustomJwtConverter extends JwtAccessTokenConverter { @Override protected Map<String, Object> convertAccessToken(OAuth2AccessToken token, OAuth2Authentication authentication) { // 先调用父类生成默认的claims Map<String, Object> claims = super.convertAccessToken(token, authentication); // 移除或修改默认声明 claims.remove("client_id"); claims.remove("jti"); // 比如修改exp的值 // claims.replace("exp", yourCustomExpTimeInSeconds); return claims; } }
然后把这个自定义转换器注册成Bean:
@Bean public JwtAccessTokenConverter jwtAccessTokenConverter() { CustomJwtConverter converter = new CustomJwtConverter(); converter.setSigningKey("your-secure-signing-key"); // 记得设置你的签名密钥 return converter; }
一些重要的提醒
- 像
exp(过期时间)属于JWT的标准声明,很多客户端或资源服务器会默认校验它,如果移除的话可能导致令牌被判定为无效,修改前一定要确认上下游系统的兼容性。 jti是令牌的唯一ID,移除后可能无法实现令牌撤销、重复使用检测等功能,要结合你的业务场景来决定是否删除。- 如果你用的是Spring Security 5.x及以上的OAuth2资源服务器,修改JWT声明后要同步调整资源服务器的验证配置,确保它能正确解析修改后的令牌。
内容的提问来源于stack exchange,提问作者Incredible
相关产品推荐
相关产品推荐

