1

I am trying to logout by revoking access_token like this :

@FrameworkEndpoint
public class SecurityLogoutController {
  @Autowired
  private ConsumerTokenServices                 consumerTokenServices;

  @DeleteMapping( "/oauth/token" )
  public ResponseEntity<Void> logout( WebRequest request ) {
    String bearer = "bearer";
    String authorizationHeader = request.getHeader( HttpHeaders.AUTHORIZATION );
    log.info( "authorization header: {}", authorizationHeader );
    if ( authorizationHeader != null && StringUtils.containsIgnoreCase( authorizationHeader, bearer ) ) {
        String accessTokenID = authorizationHeader.substring( bearer.length() + 1 );
        log.info( "access_token: {}", accessTokenID );
        consumerTokenServices.revokeToken( accessTokenID );
    }
    return ...;
  }
}

But every time I send this delete request with Postman I got this response:

{
 "timestamp": "2018-05-30T01:09:11.710+0000",
 "status": 401,
 "error": "Unauthorized",
 "message": "Unauthorized",
 "path": "/oauth/token"
}

The endpoint is protected by Spring Security behind the scene and I don't know how and where this endpoint is protected. What I don't understand is: why the client should authenticate again since to get the access_token it had been authenticated? It seems strange for me.

Now when I authenticate the client, Postman automatically replace the Authorization header value and set it with basic authentication. Something like: Basic Y2hpY293YS11aXNlcnZpY2U6Y2aXNlcnZpY2U=

Need some helps... Thanks

1 Answer 1

3

It actually makes sense because a logout can be done with the provided token by the one who already is logged in. The browser app will for sure have the client_id and secret to pass.

Even I have same problem and have posted the same on SO. Well.. one way out is that you do basic authentication with client_id and secret and importantly pass another header called AUTH-TOKEN (or something else) with the value of the actual token that you want to delete. Here is the code

@RequestMapping(method = RequestMethod.DELETE, value = "/oauth/token")
@ResponseBody
public void revokeToken(HttpServletRequest request) {
    String authorization = request.getHeader("AUTH-TOKEN");
    if (authorization != null && authorization.contains("Bearer")) {
                String tokenId = authorization.substring("Bearer".length() + 1);
                System.out.println("tokenId : " + tokenId);
                tokenServices.revokeToken(tokenId);
                //tokenStore.removeRefreshToken(token);   
     }
} 
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for this explanation. So, is it just a test issue with Postman? I mean if I use a browser (or mobile) client app with its credential (client_id + secret), the code will work?
This is an issue with NOT just postman I believe; though I did not test the same through the app.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.