java Spring Security Oauth2:处理过期 AccessToken 的流程
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27392999/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring Security Oauth2: Flow to Handling Expired AccessToken
提问by ericagon
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.
我只是 Spring Security Oauth2 的初学者。我尝试制作授权服务器和资源服务器(分离并连接到JDBC),目的是进行单点登录。我的流程成功从授权服务器获取访问令牌和刷新令牌。我的访问令牌始终用作访问资源服务器的参数,这是返回响应。
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?
我的问题,如果访问令牌过期,spring security 将阻止访问该页面并给出错误异常。何时必须使用 refreshtoken 来获取新令牌?还是我的流程不对?是否有其他流程来更新访问令牌?
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.
仅供参考:我想使用 Spring Security Oauth2 进行 SSO。我有几个 Apps Server(使用 Spring Framework),我想制作一台负责管理登录的服务器。我想让 Apps Server 成为资源服务器(也是客户端),所以我用 Spring Security Oauth2 制作了一个授权服务器。要访问受保护的资源服务器的用户必须登录到授权服务器(资源服务器向授权服务器授权)。它将获得一个代码,然后资源服务器将与 accessToken 和 refreshToken 交换此代码。这个流程是成功的。
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.
我还可以使用授权服务器提供的 refreshToken 请求新的 accessToken。但是我不能调用这个过程,因为如果我访问 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:
来自授权服务器的反馈:
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
资源(作为客户端)访问 url 本身
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"
回答by Dave Syer
The OAuth2 Spechas 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).
OAuth2 规范有一个关于刷新访问令牌的部分。它在 Spring OAuth 中以非常标准的方式实现(您只需将刷新令牌发布到 /token 端点)。
BTW for SSO you don't normally need a Resource Server. But that's a different question.
顺便说一句,对于 SSO,您通常不需要资源服务器。但这是一个不同的问题。