1

I'm trying to verify the claim inside the JWT token using JwtClaimsSetVerifier given by Spring Boot 2.1. The problem is that Spring always throws an exception with the default exception message:

{
    "error": "invalid_token",
    "error_description": "Cannot convert access token to JSON"
}

Even if I create a custom exception which extends the ClientAuthenticationException, I get the same exception message.

When the JWT claim verification fails, I want to modify the exception message. Here is my configuration class:

@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;
       }


}

Here is my JWTClaimVerifier class:

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());
        }
    }
}

I want an exception with my custom exception message when JWT claim verification fails, but all I get is the standard exception message thrown by Spring Security.

NatFar
  • 2,090
  • 1
  • 12
  • 29

1 Answers1

0

When the JWT claim verification fails, I want to modify the exception message.

But you do get your custom exception message.

The message you're seeing is because something else, something before the claims could be verified, failed.

If you check out the decode(String) method in JwtAccessTokenConverter, you'll see that your implementation of JwtClaimsSetVerifier is invoked after the token string has been decoded into a Jwt and the claims have been parsed. If the exception is thrown while decoding the token, your CustomClaimVerifier won't have a chance to override the exception.

Do you want to override the default exception message thrown when decoding fails?

Unfortunately, there doesn't seem to be a straightforward way of providing your own message. Perhaps you could subclass the JwtAccessTokenConverter and replace every InvalidTokenException with your own:

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;
    }
}
NatFar
  • 2,090
  • 1
  • 12
  • 29
  • I did see the source, since i'm throwing an exception at the verify method which is called inside the decode, the exception is thrown. Is there any other way provided by spring to verify the JWT cliams. I googled all over and this is what i can find using spring . other things using JJWT are present but i don't want to use it – vishal sundararajan Jul 29 '19 at 18:07
  • Not that I know of – NatFar Jul 29 '19 at 18:51
  • Have you checked out Spring Security 5? – NatFar Jul 29 '19 at 18:57