8

We have implemented a server API using spring-oauth2. I have noticed that the server generates the same token per user/client id combination even when calling from separate devices. This causes an issue as my clients can run multiple instances: e.g. android and ios apps. I need a way to link the token to a specific instance and not re-use the same token.

An example where this is required is for GCM (or push notification) where the API needs to know which instance it is communicating with.

This is my current spring config:

<http pattern="/oauth/token" create-session="stateless"
    authentication-manager-ref="clientAuthenticationManager"
    entry-point-ref="oauthAuthenticationEntryPoint" xmlns="http://www.springframework.org/schema/security">
    <intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY" />
    <anonymous enabled="false" />
    <http-basic entry-point-ref="oauthAuthenticationEntryPoint" />
    <!-- include this only if you need to authenticate clients via request parameters -->
    <custom-filter ref="clientCredentialsTokenEndpointFilter" before="BASIC_AUTH_FILTER" />
    <access-denied-handler ref="oauthAccessDeniedHandler" />
</http>
<oauth:authorization-server
    client-details-service-ref="mongoclientDetails" token-services-ref="tokenServices"
    user-approval-handler-ref="userApprovalHandler">
    <!-- authorization-endpoint-url="/oauth/authorize"  token-endpoint-url="/oauth/token"> -->
    <oauth:authorization-code />
    <oauth:implicit />
    <oauth:refresh-token />
    <oauth:client-credentials />
    <oauth:password />
</oauth:authorization-server>

I prefer not to give each of the clients a different id as that would be it impractical. Any ideas?

checklist
  • 12,340
  • 15
  • 58
  • 102
  • Did you get an answer to this? I'm running into similar issue. – pacman Oct 01 '15 at 16:17
  • Take a look at this. See if it helps.. http://stackoverflow.com/questions/27020702/spring-oauth2-generate-access-token-per-request-to-the-token-endpoint – pacman Oct 01 '15 at 18:28
  • I was able to solve this issue by using scope. I posted an answer. Hope it helps.. – pacman Oct 01 '15 at 21:17

2 Answers2

5

So the DefaultAuthenticationKeyGeneration uses client_id, and scope to create a key and if that matches in the request to get token it serves up the previously generated token. So in your case, you could have ios, android, and the device id for scopes.

Here is my code.

@Configuration
@EnableAuthorizationServer
protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {

.....

@Override
public void configure(ClientDetailsServiceConfigurer clients) {
    clients.inMemory()
    .withClient("my-trusted-client-with-secret")
        .authorizedGrantTypes("client_credentials")
        .authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT")
        //.scopes("read", "write", "trust")
        .secret("somesecret")
    .accessTokenValiditySeconds(3600);
}

}

Tests

» curl -H "Accept: application/json" my-trusted-client-with-secret:somesecret@localhost:8080/auth/oauth/token -d grant_type=client_credentials -d custid=1 -d siteid=2D -d scope="y"
{"access_token":"cust:site1:2D","token_type":"bearer","expires_in":3282,"scope":"y"}%                                               

» curl -H "Accept: application/json" my-trusted-client-with-secret:somesecret@localhost:8080/auth/oauth/token -d grant_type=client_credentials -d custid=1 -d siteid=3D -d scope="z"
{"access_token":"cust:site1:3D","token_type":"bearer","expires_in":3290,"scope":"z"}%                                               

» curl -H "Authorization: Bearer cust:site:3D" http://localhost:8080/dtn-auth/home
{"error":"invalid_token","error_description":"Invalid access token: cust:site:3D"}%                                                       

» curl -H "Authorization: Bearer cust:site1:3D" http://localhost:8080/dtn-auth/home
Hello World%                                                                                                                              

» curl -H "Authorization: Bearer cust:site1:2D" http://localhost:8080/dtn-auth/home
Hello World%

As you see I was able to generate multiple tokens for the same client_id and both of these tokens authenticated to access a resource from the resource server.

pacman
  • 1,061
  • 1
  • 17
  • 36
0

I think that you can take device ids in your request and generate token for each id or you can get flag that determine the type of device that call your api like ( Android, IOS) and generate token for each platform.

abozaid
  • 967
  • 8
  • 11
  • A user can have multiple devices on the same platform. In any case, we need to be able to process the id on the server. Not sure how spring would do that – checklist Sep 26 '15 at 18:54
  • The relation between user and access token must be one to many so the user can have more than on token but when the user change his password you will revoke all token so you can be able to generate more than one token to single user in the same platform. – abozaid Sep 26 '15 at 20:06