无法为 JWT CustomClaimVerifier 抛出自定义异常消息
Posted
技术标签:
【中文标题】无法为 JWT CustomClaimVerifier 抛出自定义异常消息【英文标题】:Cannot throw custom exception message for JWT CustomClaimVerifier 【发布时间】:2019-12-06 23:12:30 【问题描述】:我正在尝试使用 Spring Boot 2.1 提供的 JwtClaimsSetVerifier
验证 JWT 令牌中的声明。问题是Spring总是抛出一个带有默认异常消息的异常:
"error": "invalid_token",
"error_description": "Cannot convert access token to JSON"
即使我创建了扩展 ClientAuthenticationException
的自定义异常,我也会收到相同的异常消息。
当 JWT 声明验证失败时,我想修改异常消息。这是我的配置类:
@Configuration
@EnableResourceServer
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class ResourceserverConfig extends ResourceServerConfigurerAdapter
@Autowired
private DataSource dataSource;
@Override
public void configure(HttpSecurity http) throws Exception
http.authorizeRequests().anyRequest().permitAll().and()
.exceptionHandling().accessDeniedHandler(new CustomAccessDeniedHandler());
@Bean
public DataSource getDataSource()
return dataSource;
@Bean
public JwtAccessTokenConverter accessTokenConverter()
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey("qwerty123");
converter.setJwtClaimsSetVerifier(jwtClaimsSetVerifier());
return converter;
@Bean
public AuthenticationFailureHandler authenticationFailureHandler()
return new RestAuthenticationFailureHandler();
@Bean
public JwtClaimsSetVerifier jwtClaimsSetVerifier()
return new DelegatingJwtClaimsSetVerifier(Arrays.asList(customJwtClaimVerifier()));
@Bean
public JwtClaimsSetVerifier customJwtClaimVerifier()
return new CustomClaimVerifier();
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception
TokenStore tokenStoreRes = new JdbcTokenStore(dataSource);
resources.resourceId("RESOURCE").tokenStore(tokenStoreRes);
@Bean
@Primary
public DefaultTokenServices tokenJWTServices()
DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
TokenStore tokenStoreRes = new JwtTokenStore(accessTokenConverter());
defaultTokenServices.setTokenStore(tokenStoreRes);
defaultTokenServices.setSupportRefreshToken(true);
return defaultTokenServices;
这是我的JWTClaimVerifier
课程:
public class CustomClaimVerifier implements JwtClaimsSetVerifier
@Autowired
HttpServletRequest request;
@Override
public void verify(Map<String, Object> claims) throws InvalidTokenException
try
JsonParser parser = new JsonParser();
String json = new Gson().toJson(claims.get("userdetails"));
JsonElement menu = parser.parse(json);
String menuList = menu.getAsJsonObject().get("menu").getAsString();
boolean isMenuAccessible = validateAccessForMenu(request.getHeader("menuClicked"), menuList);
if(!isMenuAccessible)
throw new InvalidTokenException("Invalid Permissions");
catch (Exception e)
throw new InvalidTokenException(e.getMessage());
当 JWT 声明验证失败时,我想要一个带有自定义异常消息的异常,但我得到的只是 Spring Security 抛出的标准异常消息。
【问题讨论】:
【参考方案1】:当 JWT 声明验证失败时,我想修改异常消息。
但您确实收到了自定义异常消息。
您看到的消息是因为其他事情,在声明可以被验证之前的事情,失败了。
如果您查看JwtAccessTokenConverter
中的decode(String)
方法,您会看到您的JwtClaimsSetVerifier
实现是在令牌字符串被调用之后调用的解码为 Jwt 并且声明已被解析。如果在解码令牌时抛出异常,您的 CustomClaimVerifier
将没有机会覆盖该异常。
是否要覆盖解码失败时抛出的默认异常信息?
很遗憾,似乎没有一种直接的方式来提供您自己的信息。也许您可以将JwtAccessTokenConverter
子类化并用您自己的替换每个InvalidTokenException
:
public class CustomJwtAccessTokenConverter extends JwtAccessTokenConverter
@Override
protected Map<String, Object> decode(String token)
Map<String, Object> pieces = null;
try
pieces = super.decode(token);
catch(InvalidTokenException ex)
throw new InvalidTokenException("MY CUSTOM MESSAGE");
return pieces;
【讨论】:
我确实看到了源代码,因为我在解码内部调用的 verify 方法中抛出异常,所以抛出异常。 spring 是否提供了其他方法来验证 JWT cliams。我用谷歌搜索了一遍,这就是我可以使用 spring 找到的。有其他使用 JJWT 的东西,但我不想使用它 我不知道 你检查过 Spring Security 5 吗?以上是关于无法为 JWT CustomClaimVerifier 抛出自定义异常消息的主要内容,如果未能解决你的问题,请参考以下文章
将 Asp.Net Core 1 转换为 Core 2 后 Jwt 无法正常工作
无法使用 JWT 令牌连接到 Apple App Store API