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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With