Customization Spring Security 403

Asked

Viewed 709 times

3

Fala galera!

Follow my lead:

I have an application with JWT authentication. The authentication is done in the database and I need to add now 2 more validations: failed count on login and registered device. To do this, I created a class CustomDaoAuthenticationProvider except for the Daoauthenticationprovider (that second provided in Spring).

Within that class, I’ve overturned the method additionalAuthenticationChecks and wrote the appropriate validations, each casting a different exception (Lockedexception and Badcredentialsexception - both daughters of Authenticationexception)

What I need:

The return of the request comes with the respective validation message.

What is going on:

In case of failure, the return always comes the following:

{
    "timestamp": 1548779620976,
    "status": 403,
    "error": "Forbidden",
    "message": "Access Denied",
    "path": "/app/api/v1.1/login"
}

What I’ve tried to do to solve the case:

  • In Jwtloginfilter I overwrote the unSuccessfulAuthentication method and made a Rewatch.sendError(). Result: the method is even called, but the default message keeps returning.
  • In Jwauthenticationfilter I put a Try/catch block around the authenticator call aiming to capture and launch the exception, but this does not occur since apparently the exception treatment occurs before.
  • I created a Customauthenticationentrypoint following the suggestion in: https://stackoverflow.com/questions/48306302/spring-security-creating-403-access-denied-custom-response. The message even changed, but some other exception overlapped with mine and the return was:

    { "message": "Full Authentication is required to access this Resource", "timestamp": 1548780759071, "status": 403 }

In the latter case I set in message value the message presents in my exception. Does anyone have any idea how I can solve this case? I appreciate your attention.

1 answer

0


You could create an Handler and treat a specific exception for these occasions, for example:

@ControllerAdvice
public class AppExceptionHandler {

    @ExceptionHandler(value = {UserServiceException.class})
    public ResponseEntity<Object> handleUserServiceException(UserServiceException ex, WebRequest request) {
        return new ResponseEntity<Object>(new ErrorMessage(new Date(), ex.getMessage()), new HttpHeaders(), HttpStatus.BAD_REQUEST);
    }

    @ExceptionHandler(value = {Exception.class})
    public ResponseEntity<Object> handleException(Exception ex, WebRequest request) {
        return new ResponseEntity<Object>(new ErrorMessage(new Date(), ex.getMessage()), new HttpHeaders(), HttpStatus.INTERNAL_SERVER_ERROR);
    }

}

In my case I am returning to the following entity:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class ErrorMessage {

    private Date timestamp;
    private String message;

}

When I launch a UserServiceException, get the following return:

{
    "timestamp": "2019-02-07T14:17:55.639+0000",
    "message": "Record with provided id is not found"
}

Of course you need other information in return, but you can complement your ErrorMessage according, in the same way as you can create a new exception related to your authentication flow and handle on Handler.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.