0

I use Spring Security with OAuth 2. My OAuth users have account_locked and enabled fields and I use them for different reasons. E.g. account_locked for blocking users and enabled for deactivating users. When user tries to log in and has block, then he receives 401 HTTP code and message "User account is locked". If he is deactivated, then he also receives 401 HTTP code and message "User is disabled".

I want to enhance these errors with additional information(like it is possible to enhance token using TokenEnhancer) to distinguish block code from deactivated code on the client. E.g. with the field reason_of_fail. Please note that I don't want to use text messages from these errors.

I already tried to use this(from this answer):

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.exceptionHandling()
            .authencationEntryPoint(unauthorizedHandler)  
            .accessDeniedHandler(accessDeniedHandler);    
}

But these handlers doesn't catch LockedException and DisabledException.

So, how I can enhance these errors with additional field(key-value pair)?

konstantin_doncov
  • 2,725
  • 4
  • 40
  • 100

1 Answers1

3

Authorization server

If you would like to add this functionality to your authorization server, and you have a custom AbstractTokenGranter (see conversation below), then you can catch the desired exceptions in the getOAuth2Authentication method.
You can then throw a custom exception that extends OAuth2Exception and populates the additionalInformation map with any of the additional fields you require.
For an example of how to do this you can see the ResourceOwnerPasswordTokenGranter from the spring-security-oauth project.

Client

If, instead, you would like to add this functionality to your OAuth2 client, then you can use a custom AuthenticationFailureHandler to catch the LockedException and DisabledException.
Here is an example security configuration:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .oauth2Login()
            .failureHandler(new CustomAuthenticationFailureHandler());
}

And an example of a custom AuthenticationFailureHandler:

public class CustomAuthenticationFailureHandler implements AuthenticationFailureHandler {
    @Override
    public void onAuthenticationFailure(HttpServletRequest request,
            HttpServletResponse response, AuthenticationException exception) {
        if (exception instanceof DisabledException) {
            // throw new exception or modify response
        }
    }
}
  • Thanks! Unfortunately it's still the same - `onAuthenticationFailure()` just not called. But I have 3 points: 1. When I added your code, I got `ClassNotFoundException`, then I added `spring-security-oauth2-client` in `pom` and got `Bean method 'clientRegistrationRepository' not loaded because OAuth2 Clients Configured Condition registered clients is not available`, it's [described here](https://github.com/spring-projects/spring-boot/issues/12654#issuecomment-505295787). So, do I need to add these properties(duplicate them), if I already have `oauth_client_details` table with clients in my DB? – konstantin_doncov Jun 25 '19 at 15:10
  • 2. These properties are not exactly the same as existing properties in the DB. In `oauth_client_details` table I have these columns:`client_id,resource_ids,client_secret,scope,authorized_grant_types,web_server_redirect_uri,authorities,access_token_validity,refresh_token_validity,additional_information,...`, but properties in `application.properties` should have another structure and fields(as it described [here](https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-security-oauth2-client)). How should I map existing properties from DB in `application.properties`? – konstantin_doncov Jun 25 '19 at 15:11
  • 3. Will the original problem be solved after solving these two points? – konstantin_doncov Jun 25 '19 at 15:12
  • @don-prog The configuration that I mentioned is for the client side. Based on your comments, I now understand that you want to add this functionality to your authorization server, and not the client, is that correct? Additionally, can you share which endpoint you are receiving the 401 response from? – Eleftheria Stein-Kousathana Jun 25 '19 at 18:56
  • Yes, it's correct. I receive 401 from `localhost:8443/oauth/token` – konstantin_doncov Jun 26 '19 at 03:46
  • @don-prog And which grant_type are you using? Different grant types can give different error codes. – Eleftheria Stein-Kousathana Jun 26 '19 at 20:35
  • I use my custom `grant_type`s – konstantin_doncov Jun 26 '19 at 20:45
  • @don-prog Do you also have custom `AbstractTokenGranter`s? – Eleftheria Stein-Kousathana Jun 26 '19 at 21:12
  • Yes, I also have custom granters. – konstantin_doncov Jun 26 '19 at 21:23
  • 1
    @don-prog You can catch the desired exceptions in you `getOAuth2Authentication` method. See the [ResourceOwnerPasswordTokenGranter](https://github.com/spring-projects/spring-security-oauth/blob/7bfe08d8f95b2fec035de484068f7907851b27d0/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/password/ResourceOwnerPasswordTokenGranter.java) for an example. You can then throw a custom exception that extends `OAuth2Exception` and populates the `additionalInformation` map with any of the additional fields you require. – Eleftheria Stein-Kousathana Jun 26 '19 at 21:34
  • Thanks, it's works! Please, add information from your last comment in your answer, I want to accept it. – konstantin_doncov Jun 26 '19 at 22:40