spring - 无法为 JWT CustomClaimVerifier 抛出自定义异常消息
问题描述
我正在尝试使用JwtClaimsSetVerifier
Spring Boot 2.1 给出的 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 抛出的标准异常消息。
解决方案
当 JWT 声明验证失败时,我想修改异常消息。
但是您确实收到了自定义异常消息。
您看到的消息是因为其他事情,在声明可以验证之前的事情,失败了。
如果您查看 中的decode(String)
方法JwtAccessTokenConverter
,您将看到在令牌字符串被解码为 Jwt 并且声明已被解析之后JwtClaimsSetVerifier
调用了您的实现。如果在解码令牌时抛出异常,您将没有机会覆盖该异常。CustomClaimVerifier
是否要覆盖解码失败时抛出的默认异常消息?
不幸的是,似乎没有一种直接的方式来提供您自己的信息。也许你可以继承并用你自己的JwtAccessTokenConverter
替换every :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;
}
}
推荐阅读
- macos - 哪些 API 触发“应用程序想使用辅助功能控制这台计算机”?
- asterisk - 我什么时候应该在星号语法中使用 $()?
- oop - 是否有更好的替代方法来检查具有可选接口的成员的集合?
- r - 在 R 中使用 lm() 成对删除?
- ruby - 忽略数组选择中的 nil 参数
- javascript - Mongoose:复制查询结果
- javascript - 承诺条件相等
- linux - 使用set -e后如何让bash脚本不退出错误?
- node.js - 在我的节点 js 项目中使用 express-fileupload 上传错误
- python - 如何解决 VsCode 上 Python 3.7 和 OpenCV 4.1.1 中的“import cv2, ImportError: DLL load failed”?