[英]How to make the refresh token life long valid and issue a new refresh token each time a new refresh_token grant_type comes in spring security oauth2
I am using spring security oauth2 for authentication for my android application clients.When the client request comes with grant_type as password the server issues the access token and refresh token.If the access token expires i can issue a new access token by sending a request with grant_type as refresh_token.Now what will i do if my refresh token expires?I dont want to prompt the users to authenticate again using his credentials.So is there a way to issue a new refresh token along with the new access token? 我正在使用spring security oauth2对我的android应用程序客户端进行身份验证。当客户端请求带有grant_type作为密码时,服务器会发出访问令牌并刷新令牌。如果访问令牌过期,我可以通过发送请求来发出新的访问令牌grant_type as refresh_token.Now如果我的刷新令牌到期我该怎么办?我不想提示用户使用他的凭证再次进行身份验证。那么有没有办法发布新的刷新令牌以及新的访问令牌? or is there any provision to issue a refresh token with infinite validity or by sending a refresh token with single time use only and refresh the refresh token in each refresh_token grant_type request.Below is my configuration file for spring security oauth2.
或者是否有任何规定来发布具有无限有效性的刷新令牌,或者通过仅使用一次性发送刷新令牌并刷新每个refresh_token grant_type请求中的刷新令牌。下面是我的spring security oauth2的配置文件。
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:oauth="http://www.springframework.org/schema/security/oauth2"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:sec="http://www.springframework.org/schema/security" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2-1.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd ">
<!-- This is default url to get a token from OAuth -->
<http pattern="/oauth/token" create-session="stateless"
authentication-manager-ref="clientAuthenticationManager"
xmlns="http://www.springframework.org/schema/security">
<intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY" />
<anonymous enabled="false" />
<http-basic entry-point-ref="clientAuthenticationEntryPoint" />
<!-- include this only if you need to authenticate clients via request
parameters -->
<custom-filter ref="clientCredentialsTokenEndpointFilter"
after="BASIC_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>
<!-- This is where we tells spring security what URL should be protected
and what roles have access to them -->
<http pattern="/protected/**" create-session="never"
entry-point-ref="oauthAuthenticationEntryPoint"
access-decision-manager-ref="accessDecisionManager"
xmlns="http://www.springframework.org/schema/security">
<anonymous enabled="false" />
<intercept-url pattern="/protected/**" access="ROLE_APP" />
<custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>
<bean id="oauthAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="test" />
</bean>
<bean id="clientAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="test/client" />
<property name="typeName" value="Basic" />
</bean>
<bean id="oauthAccessDeniedHandler"
class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" />
<bean id="clientCredentialsTokenEndpointFilter"
class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
<property name="authenticationManager" ref="clientAuthenticationManager" />
</bean>
<bean id="accessDecisionManager" class="org.springframework.security.access.vote.UnanimousBased"
xmlns="http://www.springframework.org/schema/beans">
<constructor-arg>
<list>
<bean class="org.springframework.security.oauth2.provider.vote.ScopeVoter" />
<bean class="org.springframework.security.access.vote.RoleVoter" />
<bean class="org.springframework.security.access.vote.AuthenticatedVoter" />
</list>
</constructor-arg>
</bean>
<authentication-manager id="clientAuthenticationManager"
xmlns="http://www.springframework.org/schema/security">
<authentication-provider user-service-ref="clientDetailsUserService" />
</authentication-manager>
<authentication-manager alias="authenticationManager"
xmlns="http://www.springframework.org/schema/security">
<authentication-provider user-service-ref="userService">
</authentication-provider>
</authentication-manager>
<bean id="userService"
class="com.example.myproject.ser.UserService">
</bean>
<bean id="clientDetailsUserService"
class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
<constructor-arg ref="clientDetails" />
</bean>
<!-- This defined token store, we have used inmemory tokenstore for now
but this can be changed to a user defined one -->
<bean id="tokenStore"
class="org.springframework.security.oauth2.provider.token.InMemoryTokenStore" />
<!-- This is where we defined token based configurations, token validity
and other things -->
<bean id="tokenServices"
class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
<property name="tokenStore" ref="tokenStore" />
<property name="supportRefreshToken" value="true" />
<property name="accessTokenValiditySeconds" value="120" /> <!-- 2 hour 3600 -->
<property name="refreshTokenValiditySeconds" value="420"></property> <!-- 2 month 5270400 -->
<property name="clientDetailsService" ref="clientDetails" />
</bean>
<bean id="userApprovalHandler"
class="org.springframework.security.oauth2.provider.approval.TokenServicesUserApprovalHandler">
<property name="tokenServices" ref="tokenServices" />
</bean>
<oauth:authorization-server
client-details-service-ref="clientDetails" token-services-ref="tokenServices"
user-approval-handler-ref="userApprovalHandler">
<oauth:authorization-code />
<oauth:implicit />
<oauth:refresh-token />
<oauth:client-credentials />
<oauth:password />
</oauth:authorization-server>
<oauth:resource-server id="resourceServerFilter"
resource-id="test" token-services-ref="tokenServices" />
<bean id="clientDetails"
class="com.example.myproject.ser.ClientService">
</bean>
<sec:global-method-security
pre-post-annotations="enabled" proxy-target-class="true">
<!--you could also wire in the expression handler up at the layer of the
http filters. See https://jira.springsource.org/browse/SEC-1452 -->
<sec:expression-handler ref="oauthExpressionHandler" />
</sec:global-method-security>
<oauth:expression-handler id="oauthExpressionHandler" />
<oauth:web-expression-handler id="oauthWebExpressionHandler" />
</beans>
In my android application i have the provision to authenticate the same user from multiple devices.That is one can authenticate in any device if already he is authenticated in other device.So the solution don't affect this case. 在我的Android应用程序中,我有从多个设备验证同一用户的规定。如果已经在其他设备中对其进行了身份验证,那么可以在任何设备中进行身份验证。因此解决方案不会影响这种情况。
You can set validity period for the refresh token either at the client level (see org.springframework.security.oauth2.provider.ClientDetails and org.springframework.security.oauth2.provider.ClientDetailsService). 您可以在客户端级别设置刷新令牌的有效期(请参阅org.springframework.security.oauth2.provider.ClientDetails和org.springframework.security.oauth2.provider.ClientDetailsService)。 You'll need to set this on the client as it's loaded by the client details service.
您需要在客户端详细信息服务加载的客户端上设置此项。
public classs MyClientDetailsService implements ClientDetailsService {
@Override
public ClientDetails loadClientByClientId(String clientId) throws ClientRegistrationException {
BaseClientDetails client = new BaseClientDetails();
client.setRefreshTokenValiditySeconds(Integer.MAX_VALUE);
...
return client;
}
}
Alternatively, you can set a default validity on org.springframework.security.oauth2.provider.token.DefaultTokenServices (assuming that is the implementation that you are using in your server) in your authorisation server configuration. 或者,您可以在授权服务器配置中的org.springframework.security.oauth2.provider.token.DefaultTokenServices上设置默认有效性(假设这是您在服务器中使用的实现)。 You can do this by adding the following method to your authorisation server configuration class.
您可以通过将以下方法添加到授权服务器配置类来完成此操作。
@Bean
public AuthorizationServerTokenServices authorizationServerTokenServices() throws Exception {
DefaultTokenServices tokenServices = new DefaultTokenServices();
tokenServices.setTokenStore(tokenStore);
tokenServices.setSupportRefreshToken(true);
tokenServices.setClientDetailsService(clientDetailsService);
tokenServices.setRefreshTokenValiditySeconds(Integer.MAX_VALUE);
return tokenServices;
}
Once that refresh token has expired though, I believe the only way to obtain a new one is for the user to re-authenticate. 一旦刷新令牌已经过期,我相信获得新令牌的唯一方法是让用户重新进行身份验证。
According to the source code for spring-security-oauth
in the DefaultTokenServices
passing a value less or equal to zero as the validity of the refresh token should be enough to make it last forever. 根据
DefaultTokenServices
spring-security-oauth
的源代码传递一个小于或等于零的值,因为刷新令牌的有效性应足以使其永久持续。 Check it out here . 在这里查看 。
Then the code in the authorisation server configuration should be like this: 然后授权服务器配置中的代码应如下所示:
@Bean
fun tokenServices(): DefaultTokenServices {
val defaultTokenServices = DefaultTokenServices()
defaultTokenServices.setTokenStore(tokenStore())
defaultTokenServices.setRefreshTokenValiditySeconds(0)
return defaultTokenServices
}
Or if you have a JdbcClientDetailsService
you can set the refresh token expiry in the oauth_client_details
table. 或者,如果您有
JdbcClientDetailsService
,则可以在oauth_client_details
表中设置刷新令牌到期。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.