5
votes

I am just a beginner in Spring Security Oauth2. I try to make Authorization Server and Resource Server (separated and connect to JDBC) and the purpose is to make Single Sign-On. My flow success to get accesstoken and refreshtoken from Authorization Server. My accesstoken always used as parameter to access Resouce Server, and this is give a response back.

for example http://127.0.0.1:8080/Resource/res/staff?access_token=xxxxxxxxxxxxxxxxxxxxx

My problem, if the accesstoken expired, the spring security will prevent to access the page and give the error exception. When I must use the refreshtoken to get new token? Or is my flow wrong? Is there other flow to renew accesstoken?

Thanks

Edited:

FYI: I want to make SSO using Spring Security Oauth2. I have several Apps Server (use Spring Framework) and I want to make one server that responsible to manage the login. And I want to make the Apps Server become Resource Server (also the Client) So I make one Authorization Server with Spring Security Oauth2. The user who wants to access the protected Resource Server must login to Authorization Server (the Resource Server authorize to Authorization Server). It will get a code and then the Resource Server will exchange this code with accessToken and refreshToken. This flow is success.

I can also request the new accessToken using the refreshToken that given by Authorization Server. But I cannot call this procedure because if I access the url mapping, previously the spring security was blocking the access and give the invalid token error return.

How can I solve the missing link?

Updated:

This is my Authorization Server Configuration:

@Configuration
public class Oauth2AuthorizationServer {

 @Configuration
 @EnableAuthorizationServer
 protected static class AuthorizationServerConfiguration extends
        AuthorizationServerConfigurerAdapter {

    @Autowired
    @Qualifier("authenticationManagerBean")
    private AuthenticationManager authenticationManager;

    @Autowired
    DataSource dataSource;


    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints)
            throws Exception {
        endpoints
                .tokenStore(new JdbcTokenStore(dataSource))
                .authenticationManager(authenticationManager);
    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
        oauthServer.tokenKeyAccess("isAnonymous() || permitAll()").checkTokenAccess("permitAll()");
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients
                .jdbc(dataSource);
    }
 }
}

And this is my Resource Server Configuration (as Client too)

@Configuration
public class Oauth2ResourceServer {

private static final String RESOURCE_ID = "test";

 @Configuration @Order(10)
 protected static class NonOauthResources extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/api/halo").permitAll()
                .antMatchers("/api/state/**").permitAll()
                .antMatchers("/**").permitAll()
                .and().anonymous();
    }
 }

 @Configuration
 @EnableResourceServer
 protected static class ResourceServerConfiguration extends
        ResourceServerConfigurerAdapter {

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) {
        RemoteTokenServices tokenService = new RemoteTokenServices();
        tokenService.setClientId("jsclient");
        tokenService.setClientSecret("jspasswd");
        tokenService.setCheckTokenEndpointUrl("http://localhost:8084/Server2Auth/oauth/check_token");

        resources
                .resourceId(RESOURCE_ID)
                .tokenServices(tokenService);
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .filterSecurityInterceptorOncePerRequest(true)
                .antMatchers("/res/staff").hasRole("STAFF")
                .antMatchers("/res/client").access("#oauth2.hasScope('trust')")
                .antMatchers("/res/admin").hasRole("ADMIN")
                .and()
                .exceptionHandling().accessDeniedPage("/403");
    }

 }

}

Resource (as Client too) request to authorize:

curl -X POST -vu clientauthcode:123456 http://localhost:10000/auth-server/oauth/token -d "client_id=clientauthcode&grant_type=refresh_token&refresh_token=436761f1-2f26-412b-ab0f-bbf2cd7459c4"

Feedback from Authorize Server:

http://localhost:10001/resource-server/api/state/new?code=8OppiR

Resource (as Client) exchange the code to Authorize Server:

curl -X POST -vu clientauthcode:123456 http://localhost:10000/auth-server/oauth/token -H "Accept: application/json" -d "grant_type=authorization_code&code=iMAtdP&redirect_uri=http://localhost:10001/resource-server/api/state/new"

Feedback from Authorize Server:

{
    "access_token":"08664d93-41e3-473c-b5d2-f2b30afe7053",
    "token_type":"bearer",
    "refresh_token":"436761f1-2f26-412b-ab0f-bbf2cd7459c4",
    "expires_in":43199,
    "scope":"write read"
}

Resource (as Client) access the url itself

curl http://localhost:10001/resource-server/api/admin?access_token=08664d93-41e3-473c-b5d2-f2b30afe7053

Request new access toke using refresh token

curl -X POST -vu clientauthcode:123456 http://localhost:10000/auth-server/oauth/token -d "client_id=clientauthcode&grant_type=refresh_token&refresh_token=436761f1-2f26-412b-ab0f-bbf2cd7459c4"
1
Unrelated comment: you should put the access token in a header (it's not secure as a URI query parameter).Dave Syer
Another unrelated comment: you don't need the token key endpoint, so don't touch it; and the check token endpoint should not be exposed with permitAll() in a production server (try isAuthenticated()).Dave Syer
Somewhat related comment (since it makes the question misleading) you are not doing any SSO here. It is classic auth/resource server with token-based security in the resource server.Dave Syer
I think the curl command for the authorization code is wrong (copy paste error)?Dave Syer
Maybe the clientID, clientSecret or the code are different. I can use the curl (with change the clientID, clientSecret, and code)ericagon

1 Answers

2
votes

The OAuth2 Spec has a section on refreshing access tokens. It's implemented in a pretty standard way in Spring OAuth (you just post the refresh token to the /token endpoint).

BTW for SSO you don't normally need a Resource Server. But that's a different question.