Spring securityouth2 refresh token

  spring-security

Order

This article will talk about spring security oauth2′ s refresh token method.

authorizedGrantTypes

Oauth2 has only four official authorization methods, but spring security oauth2 also classifies refresh token as one of the authorizedGrantTypes, so it is only necessary to support all methods when configuring.

@Configuration
@EnableAuthorizationServer //提供/oauth/authorize,/oauth/token,/oauth/check_token,/oauth/confirm_access,/oauth/error
public class OAuth2ServerConfig extends AuthorizationServerConfigurerAdapter {
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                .withClient("demoApp")
                .secret("demoAppSecret")
                .redirectUris("http://localhost:8081/callback") //新增redirect_uri
                .authorizedGrantTypes("authorization_code", "client_credentials", "refresh_token",
                        "password", "implicit")
                .scopes("all")
                .resourceIds("oauth2-resource")
                .accessTokenValiditySeconds(120)
                .refreshTokenValiditySeconds(60);
    }
}

Configure userDetailsService

To use refresh_token, you need to configure the userDetailsService additionally.

    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.authenticationManager(authenticationManager);
        endpoints.userDetailsService(userDetailsService);
    }

Otherwise, the error is reported as follows

HTTP/1.1 500
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
X-Application-Context: application
Cache-Control: no-store
Pragma: no-cache
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Wed, 06 Dec 2017 13:35:33 GMT
Connection: close

{"error":"server_error","error_description":"UserDetailsService is required."}

get token

curl -i -d "grant_type=authorization_code&code=uKGjVz&client_id=demoApp&client_secret=demoAppSecret&redirect_uri=http://localhost:8081/callback" -X POST http://localhost:8080/oauth/token

refresh token

curl -i -X POST  -u 'demoApp:demoAppSecret' -d 'grant_type=refresh_token&refresh_token=95844d87-f06e-4a4e-b76c-f16c5329e287' http://localhost:8080/oauth/token

Access_token and refresh_token did not expire when calling

HTTP/1.1 200
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
X-Application-Context: application
Cache-Control: no-store
Pragma: no-cache
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Wed, 06 Dec 2017 13:51:47 GMT

{"access_token":"eb45f1d4-54a5-4e23-bf12-31d8d91a902f","token_type":"bearer","refresh_token":"efa96270-18a1-432c-b9e6-77725c0dabea","expires_in":1199,"scope":"all"}

Access_token will change and expires will be extended. refresh_token will remain unchanged without expiration according to the set expiration time.

Access_token expired when called, refresh_token did not expire

HTTP/1.1 200
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
X-Application-Context: application
Cache-Control: no-store
Pragma: no-cache
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Wed, 06 Dec 2017 14:03:50 GMT

{"access_token":"a78999d6-614a-45fe-be58-d5e0b6451bdb","token_type":"bearer","refresh_token":"bb2a0165-769d-43b0-a9a5-1331012ede1f","expires_in":119,"scope":"all"}

Access_token will change and expires will be extended. refresh_token will remain unchanged without expiration according to the set expiration time.

Refresh_token expired on call

HTTP/1.1 401
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
X-Application-Context: application
Cache-Control: no-store
Pragma: no-cache
WWW-Authenticate: Bearer error="invalid_token", error_description="Invalid refresh token (expired): 95844d87-f06e-4a4e-b76c-f16c5329e287"
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Wed, 06 Dec 2017 14:09:57 GMT

{"error":"invalid_token","error_description":"Invalid refresh token (expired): 95844d87-f06e-4a4e-b76c-f16c5329e287"}

Summary

  • Refresh_token must be called before expiration to replace the token
  • As long as refresh_token is valid, it can be directly used to replace the access_token (The expiration time is the value specified in the configuration file)

doc