简体   繁体   English

Spring Security Oauth2:处理过期的AccessToken的流程

[英]Spring Security Oauth2: Flow to Handling Expired AccessToken

I am just a beginner in Spring Security Oauth2. 我只是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. 我尝试创建授权服务器和资源服务器(分离并连接到JDBC),目的是进行单点登录。 My flow success to get accesstoken and refreshtoken from Authorization Server. 我从Authorization Server获取accessstoken和refreshtoken的流程成功。 My accesstoken always used as parameter to access Resouce Server, and this is give a response back. 我的accesstoken始终用作访问Resouce Server的参数,这将给出响应。

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. 我的问题是,如果accessstoken过期,spring安全性将阻止访问页面并给出错误异常。 When I must use the refreshtoken to get new token? 当我必须使用refreshtoken获取新令牌? Or is my flow wrong? 或者我的流程错了? Is there other flow to renew accesstoken? 还有其他流程可以更新accessstoken吗?

Thanks 谢谢

Edited: 编辑:

FYI: I want to make SSO using Spring Security Oauth2. 仅供参考:我想使用Spring Security Oauth2制作SSO。 I have several Apps Server (use Spring Framework) and I want to make one server that responsible to manage the login. 我有几个Apps Server(使用Spring Framework),我想制作一个负责管理登录的服务器。 And I want to make the Apps Server become Resource Server (also the Client) So I make one Authorization Server with Spring Security Oauth2. 我想让Apps Server成为资源服务器(也是客户端)所以我用Spring Security Oauth2创建了一个Authorization Server。 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. 它将获得一个代码,然后资源服务器将使用accessToken和refreshToken交换此代码。 This flow is success. 这种流程是成功的。

I can also request the new accessToken using the refreshToken that given by Authorization Server. 我也可以使用Authorization Server提供的refreshToken请求新的accessToken。 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. 但我无法调用此过程,因为如果我访问url映射,之前spring安全性阻止访问并返回无效标记错误。

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: 来自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: 来自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 资源(作为客户端)访问URL本身

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

Request new access toke using refresh token 使用刷新令牌请求新访问toke

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"

The OAuth2 Spec has a section on refreshing access tokens. OAuth2规范有一个关于刷新访问令牌的部分。 It's implemented in a pretty standard way in Spring OAuth (you just post the refresh token to the /token endpoint). 它在Spring OAuth中以非常标准的方式实现(您只需将刷新令牌发布到/ token端点)。

BTW for SSO you don't normally need a Resource Server. 对于SSO,BTW通常不需要资源服务器。 But that's a different question. 但这是一个不同的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM