当前位置: 首页 > 知识库问答 >
问题:

无法为JWT CustomClaimVerifier抛出自定义异常消息

柯阳曦
2023-03-14

我正在尝试使用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个答案

邵沛
2023-03-14

当JWT声明验证失败时,我想修改异常消息

但是您确实会收到自定义异常消息。

你看到的信息是因为其他的东西,在索赔可以被证实之前,失败了。

如果您查看JwtAccessTokenConverter中的decode(String)方法,您将看到在将令牌字符串解码为Jwt并解析声明之后调用了JwtClaimsSetVerifier的实现。如果在解码令牌时引发异常,则您的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;
    }
}
 类似资料:
  • 我是一名Java编程新手(实际上已经在学习),我对如何处理不同的消息有些怀疑。 我的目标是将这些不同的消息包含在同一个类(CustomExcpse类)中,以避免在从其他类抛出新CustomExceptions的每个方法上一遍又一遍地编写相同的字符串。 到目前为止,我编码: > 一个自定义异常类,它从异常扩展而来,具有不同的消息(在示例中只有两个,但还有更多)作为Strings包含,当然还有构造函数

  • "CATCH"应该严格地在"扔"之后叫吗?" 例1: 错误: 找不到方法“接收器”:没有方法缓存,也没有^在/tmp/739536251/main块中查找_方法。pl6第11行 例2: 无误

  • 我知道您可以使用try-catch块对自定义消息抛出异常,例如: 但是如果我们在实用程序类中有一个方法,例如: 然后我们进入服务类,如下所示: 有没有一种方法可以自定义设置来自实用程序类方法<code>processFiles()</code>的消息及其<code>抛出的IOException</code>,而不是在该方法内部使用try-catch块?

  • 本文向大家介绍Java抛出异常与自定义异常类应用示例,包括了Java抛出异常与自定义异常类应用示例的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Java抛出异常与自定义异常类。分享给大家供大家参考,具体如下: 异常处理常用方法: 常用的异常处理方法有: 一、try()catch() 语句 二、throw / throws 语句 三、自定义异常类 用途: 众所周知,当程序运行过程中,如果遇

  • 抛出异常有什么意义?例如,我偶然发现: 但是当你不扔零点的时候,你也会得到一个零点?我经常看到这个,我想知道这是否是一个学习的好习惯?

  • 本文向大家介绍Django 解决开发自定义抛出异常的问题,包括了Django 解决开发自定义抛出异常的问题的使用技巧和注意事项,需要的朋友参考一下 在开发过程中,针对用户输入的不合法信息,我们应该在后端进行数据验证,并抛出相关的异常传递到前端来提示用户。 可是如何进行自定义抛出异常信息呢?通常处理方法有三种,我将依次介绍这三种方法。 第一种方法: 这种方法最为简单,只需要创建一个字典对象,通过re