I am trying to get a basic in-memory OAuth2 server running using the Spring Libraries. I have been following the sparklr example.
I currently have configured the Ser
Your step #6 is wrong - the access token should not be sent in the URL as it is vulnerable this way. rathen than GET, use POST.
Besides, I don't understand your step #1 - why do you call /oauth/authorize? it should be done implicitly when you try to get a protected resource. I mean, your flow should start with:
Attempt to access a restricted resource using the access_token: http://localhost:8080/server/me
Then the negotiation will start "behind the scenes": a redirect to "/oauth/authorize" etc.
In addition, in step #8, note that you are not asking for "another access token", but instead it is a request for "refresh token". As if your access-token was expired.
Note: The identity provider and the resource server should share the tokenStore! Read here: Spring Security OAuth2 pure resource server
HTH
This works for me:
@Configuration
public class Oauth2ServerConfiguration {
private static final String SERVER_RESOURCE_ID = "oauth2-server";
@Autowired
private TokenStore tokenStore;
@Bean
public TokenStore tokenStore() {
return new InMemoryTokenStore();
}
@Configuration
@EnableResourceServer
protected static class ResourceServer extends ResourceServerConfigurerAdapter {
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.tokenStore(tokenStore).resourceId(SERVER_RESOURCE_ID);
}
@Override
public void configure(HttpSecurity http) throws Exception {
// ... Not important at this stage
}
}
@Configuration
@EnableAuthorizationServer
protected static class AuthConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager).tokenStore(tokenStore).approvalStoreDisabled();
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
//... Not important at this stage
}
}
}
The problem ended up being that the resource server and the authorization server were not getting the same token store reference. Not sure how the wiring was not working correctly, but using a fixed object in the configuration class worked like a charm. Ultimately, I'll move to a persistence backed token store, which probably would not have had any issues.
Thanks goes to @OhadR for the answer and the help!
Ultimately, I simplified the configuration, went thru the same workflow, and it worked out
@Configuration
public class Oauth2ServerConfiguration {
private static final String SERVER_RESOURCE_ID = "oauth2-server";
private static InMemoryTokenStore tokenStore = new InMemoryTokenStore();
@Configuration
@EnableResourceServer
protected static class ResourceServer extends ResourceServerConfigurerAdapter {
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.tokenStore(tokenStore).resourceId(SERVER_RESOURCE_ID);
}
@Override
public void configure(HttpSecurity http) throws Exception {
http.requestMatchers().antMatchers("/me").and().authorizeRequests().antMatchers("/me").access("#oauth2.hasScope('read')");
}
}
@Configuration
@EnableAuthorizationServer
protected static class AuthConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager).tokenStore(tokenStore).approvalStoreDisabled();
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("client")
.authorizedGrantTypes("authorization_code","refresh_token")
.authorities("ROLE_CLIENT")
.scopes("read")
.resourceIds(SERVER_RESOURCE_ID)
.secret("secret")
;
}
}
}
Anyone that stumbles upon this post, I recommend looking more at the unit tests for example rather than the full blown sparklr/tonr example, as it has a lot of extra configuration that are not necessarily needed to get started.