2016-07-27 24 views
0

我使用彈簧安全的oauth2認證爲我的Android應用程序時發出新的刷新令牌clients.When客戶端請求自帶grant_type作爲密碼服務器發出的訪問令牌和刷新token.If訪問令牌到期,我可以用grant_type發送一個請求作爲refresh_token.Now如果我的刷新令牌過期我該怎麼辦發出新的訪問令牌?我不想提示用戶使用他的憑證再次進行身份驗證。那麼是否有辦法與新的訪問令牌一起發佈新的刷新令牌?或者是否有任何規定可以發出無限有效的刷新令牌,或者只發送一次刷新令牌,並在每個refresh_token grant_type請求中刷新刷新令牌。下面是我對spring security oauth2的配置文件。如何使刷新令牌壽命長有效,每一個新的refresh_token grant_type進來春季安全的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應用程序,我必須提供認證從多個devices.That同一用戶可以在任何設備進行認證,如果他已經在其他device.So被認證的解決方案不會影響這種情況下, 。

回答

2

您可以在客戶端級別設置刷新令牌的有效期(請參閱org.springframework.security.oauth2.provider.ClientDetails和org.springframework.security.oauth2.provider.ClientDetailsS​​ervice)。 您需要在客戶端詳細信息服務加載它時在客戶端上進行設置。

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默認的有效性(假定爲您正在使用的服務器的實現)在您的授權服務器配置。您可以通過將以下方法添加到授權服務器配置類來完成此操作。

@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; 
} 

雖然刷新令牌已過期,但我相信獲得新的唯一方法是讓用戶重新進行身份驗證。

+0

什麼會爲MAX_VALUE默認值指定here.Is它有一個固定的值由SRING提供 – KJEjava48

+1

默認值是源: https://github.com/spring-projects/spring-security-oauth/ BLOB /主/彈簧安全的oauth2/src目錄/主/ JAVA /組織/ springframework的/安全/的oauth2 /供應商/令牌/ DefaultTokenServices.java –

+0

有沒有什麼辦法讓刷新令牌,因爲它永遠不會過期??? – KJEjava48

0

根據DefaultTokenServices中的spring-security-oauth的源代碼傳遞的值小於或等於零,因爲刷新令牌的有效性應該足以使其永久存在。查看here

然後在授權服務器配置的代碼應該是這樣的:

@Bean  
fun tokenServices(): DefaultTokenServices { 
    val defaultTokenServices = DefaultTokenServices() 
    defaultTokenServices.setTokenStore(tokenStore()) 
    defaultTokenServices.setRefreshTokenValiditySeconds(0) 

    return defaultTokenServices 
} 

或者,如果你有一個JdbcClientDetailsService可以設置在oauth_client_details表刷新令牌到期。