Monday, December 4, 2017

Spring oauth: Why resource server is authorising instead of authorisation server

Leave a Comment

What i found while using spring oauth framework is resource server making check_token?token=T_O_K_E_N request to authorisation server, and authorisation server is just returning CheckTokenEndPoint map with authorities something like below.

{     "exp": 1511471427,     "user_name": "idvelu",     "authorities": [         "FUNCTION_GET_USERS",         "FUNCTION_AUTHORITY_1",         "FUNCTION_AUTHORITY_2",         "FUNCTION_AUTHORITY_3",         "FUNCTION_AUTHORITY_4",         "FUNCTION_AUTHORITY_5",         "FUNCTION_AUTHORITY_6",         "FUNCTION_AUTHORITY_7",     ],     "client_id": "c1",     "scope": [         "read",         "write"     ] } 

Just visualise this with oauth service and resource service is running in two different machines/jvm.

I think now resource server has to authorise the request against configured valid authorities in ResourceServerConfiguration::configure(HttpSecurity) with the authorities from the authorisation server.

@Override public void configure(HttpSecurity http) throws Exception {  http.anonymous().disable().requestMatchers().antMatchers("/**").and().authorizeRequests()          .antMatchers(HttpMethod.GET, "/myproject/users").hasAnyAuthority("FUNCTION_GET_USERS")         .antMatchers(HttpMethod.POST, "/myproject/users").hasAnyAuthority("FUNCTION_POST_NEW_USER")         .anyRequest().denyAll()         .and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler()); } 

In this case authorisation server may return all the hundreds of user authorities to resource server. Instead why not authorisation server itself can take the few of the permission required for authorisation as query params
check_token?token=T_O_K_E_N&authorities=FUNCTION_GET_USERS,FUNCTION_AUTHORITY_2,..
from the resource server and validate it against the user's functions through DB?

And finally my problem is; i have different services like java, node.js, NGINX... All these have to verify its authentication and authorization against one spring Authorisation server. Because of the above stated problem all my service has to implement the authorisation (resource server) part. Means comparing all the authorities of user against the API acess authorities.
Java side this comparison is fine with spring resource server implementation. But all other non-java (resource) services needs authorisation/resourceServer implementation. Instead if my spring authorisation server accepts the authorities and validates then my problem is solved as single point of authorisation/comparison implementations. I just need to pass it as part of check_token.

How to implement this new check_token endpoint along with accepting the authorities?

1 Answers

Answers 1

The authorization server is responsible for authenticating the user/client (depending on the oauth type you use). When this is done, a token is given.

When a user/client presents themselves to the resource server, wanting to consume a service, they must provide the token. Now the resource server has a token and needs to validate that this token was generated by the authorization server. There are two options:

  1. The token itself does not contain any information. The resource server calls the authorization server and asks if the token is valid. The authorization server will respond that the token is valid and gives some additional information (user/client, roles/scopes, etc).
  2. The token does contain the necessary information (JWT tokes for example). This enables the resource server to extract the needed info without contacting the authorization server. In this case, the authorization server has signed the token and the resource server can validate the signature to be sure that it was the autorization server that has issued the token.

At the moment, you are using the first scenario. Every resource server you write, must verify tokens and extract additional info. How the verification is done depends on the authorization server.

Part2:

Your question is not clear to me. I presume you are using the OAuth2 authorization code scheme with non JWT tokens?

In that case, you have an authorization server that is only responsible for authentication, a resource server that is exposing some services and a client that consumes the resource server.

If i'm not mistaking, you have different resource servers (api's)?

You did not share your authorization server configurations, but normaly you use @EnableAuthorizationServer. This will create an endpoint /oauth/check_token. By default this endpoint is not accassible. You need to do something like this:

@Override public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {    oauthServer.checkTokenAccess("permitAll()"); // authenticated is better } 

You can use this endpoint to validate tokens.

All this is described in the oauth2 developer guide.

Part3:

On the authorization server, you can create an endpoint like this :

@RequestMapping("/user") public Principal user(Principal principal) {      if(principal instanceof OAuth2Authentication) {         return (OAuth2Authentication) principal;     } else {         return principal;     } } 

You can modify it to your needs.

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment