1

I am using Spring Security to construct my blog application's authentication/authorization. We've decided to use RESTful api, in order to return json message to the client while handling the authentication error in the server side, i have to write custom AuthenticationFailureHandler, like:

public class RganAuthenticationFailureHandler implements AuthenticationFailureHandler {
    private static Logger logger = LoggerFactory.getLogger(RganAuthenticationFailureHandler.class);


    @Override
    public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
        httpServletResponse.setContentType(MediaType.APPLICATION_JSON_VALUE);
        httpServletResponse.setStatus(HttpStatus.UNAUTHORIZED.value());
        httpServletResponse.getWriter().write("some description");
    }
}

The AuthenticationException have some concrete derived type, describe what's the exact error, like: UsernameNotFoundException, BadCredentialsException, AuthenticationServiceException...

It seems to me that i should return different error message for different exception type. For example, for UsernameNotFoundException and BadCredentialsException, i might return "wrong username or password, for AuthenticationServiceException, i might return "some sth wrong happen during getting your credentials, please retry later" and a different HTTP status code(like 500).

Now here's the problem, i know i can write code like:

if(e instanceof UsernameNotFoundException || e instanceof BadCredentialsException){
    httpServletResponse.getWriter.write("message1");
}else if(e instance of AuthenticationServiceException){
    httpServletResponse.getWriter.write("message2");
}else if(...){
    // ...
}

to handle this, but it seems not to be the best solution, i have to write a serie of else if block.

I've read some post like https://stackoverflow.com/a/46530064/8510613, it seems that use @ControllerAdvice and HandlerExceptionResolver is also not the best solution.

So how should i handle this problem?

user8510613
  • 1,242
  • 9
  • 27

1 Answers1

1

You could make the decision further up the stack by using DelegatingAuthenticationFailureHandler

An AuthenticationFailureHandler that delegates to other AuthenticationFailureHandler instances based upon the type of AuthenticationException passed into onAuthenticationFailure

codebrane
  • 4,290
  • 2
  • 18
  • 27