春季安全性oauth2中,如何使刷新令牌的寿命长久有效,以及每次有新的refresh_token grant_type时发出新的刷新令牌 [英] 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

查看:224
本文介绍了春季安全性oauth2中,如何使刷新令牌的寿命长久有效,以及每次有新的refresh_token grant_type时发出新的刷新令牌的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用spring security oauth2对我的android应用程序客户端进行身份验证.当客户端请求附带Grant_type作为密码时,服务器将发布访问令牌和刷新令牌.如果访问令牌过期,我可以通过发送来发行新的访问令牌现在,如果刷新令牌过期,我该怎么办?我不想提示用户使用他的凭据再次进行身份验证,那么是否有办法与新的访问令牌一起发行新的刷新令牌?或者是否有任何规定来发出具有无限有效性的刷新令牌,或者是否仅发送一次使用一次的刷新令牌并在每个refresh_token grant_type请求中刷新刷新令牌.以下是我的春季安全性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? 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.

      <?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>

在我的android应用程序中,我提供了从多个设备对同一用户进行身份验证的规定.也就是说,如果一个用户已经在其他设备上进行身份验证,则可以在任何设备上进行身份验证.因此解决方案不会影响这种情况.

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.

推荐答案

您可以在客户端级别设置刷新令牌的有效期(请参见org.springframework.security.oauth2.provider.ClientDetails和org.springframework.security. .oauth2.provider.ClientDetailsS​​ervice). 您需要在客户端详细信息服务加载的客户端上对其进行设置.

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). 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;
    }
}

或者,您可以在授权服务器配置中为org.springframework.security.oauth2.provider.token.DefaultTokenServices设置默认有效性(假设这是您在服务器中使用的实现).您可以通过在授权服务器配置类中添加以下方法来做到这一点.

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. 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.

这篇关于春季安全性oauth2中,如何使刷新令牌的寿命长久有效,以及每次有新的refresh_token grant_type时发出新的刷新令牌的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆