Spring OAuth2授权请求始终返回相同的访问令牌

Spring OAuth2授权请求始终返回相同的访问令牌,spring,spring-security,access-token,oauth2,Spring,Spring Security,Access Token,Oauth2,我将Spring3.2.11.RELEASE与OAuth2.0.7.RELEASE一起使用。我已将授权服务器配置为使用JDBC令牌存储(org.springframework.security.oauth2.provider.token.store.JdbcTokenStore类)。但是,使用grant_type=client_凭据的具有相同客户端ID的重复请求返回相同的访问令牌,即使在服务器重新启动后也是如此。令牌是有效的(它有不同的过期日期),但这似乎是一个安全缺陷。如何使重复的有效请求返回

我将Spring3.2.11.RELEASE与OAuth2.0.7.RELEASE一起使用。我已将授权服务器配置为使用JDBC令牌存储(org.springframework.security.oauth2.provider.token.store.JdbcTokenStore类)。但是,使用grant_type=client_凭据的具有相同客户端ID的重复请求返回相同的访问令牌,即使在服务器重新启动后也是如此。令牌是有效的(它有不同的过期日期),但这似乎是一个安全缺陷。如何使重复的有效请求返回不同的访问令牌?下面是我的Spring配置

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

<!-- The OAuth2 protected resources are separated out into their own block 
    so we can deal with authorization and error handling separately. This isn't 
    mandatory, but it makes it easier to control the behaviour. -->
<http pattern="/oauth/(users|clients)/.*" request-matcher="regex"
    create-session="stateless" entry-point-ref="oauthAuthenticationEntryPoint"
    use-expressions="true" xmlns="http://www.springframework.org/schema/security">
    <anonymous enabled="false" />
    <intercept-url pattern="/oauth/users/([^/].*?)/tokens/.*"
        access="#oauth2.clientHasRole('ROLE_CLIENT') and (hasRole('ROLE_USER') or #oauth2.isClient()) and #oauth2.hasScope('write')"
        method="DELETE" />
    <intercept-url pattern="/oauth/users/.*"
        access="#oauth2.clientHasRole('ROLE_CLIENT') and (hasRole('ROLE_USER') or #oauth2.isClient()) and #oauth2.hasScope('read')"
        method="GET" />
    <intercept-url pattern="/oauth/clients/.*"
        access="#oauth2.clientHasRole('ROLE_CLIENT') and #oauth2.isClient() and #oauth2.hasScope('read')"
        method="GET" />
    <custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
    <access-denied-handler ref="oauthAccessDeniedHandler" />
    <expression-handler ref="oauthWebExpressionHandler" />
</http>

<!-- The OAuth2 protected resources are separated out into their own block 
    so we can deal with authorization and error handling separately. This isn't 
    mandatory, but it makes it easier to control the behaviour. -->
<http pattern="/me/**" 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="/me" access="ROLE_USER,SCOPE_READ" />
    <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="sparklr2" />
</bean>

<bean id="clientAuthenticationEntryPoint"
    class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
    <property name="realmName" value="sparklr2/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 id="userDetailsService">
            <user name="marissa" password="koala" authorities="ROLE_USER" />
            <user name="paul" password="emu" authorities="ROLE_USER" />
        </user-service>
    </authentication-provider>
</authentication-manager>

<bean id="clientDetailsUserService"
    class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
    <constructor-arg ref="clientDetails" />
</bean>

<bean id="tokenStore"
    class="org.springframework.security.oauth2.provider.token.store.JdbcTokenStore">
    <constructor-arg ref="dataSource" />
</bean>

<bean id="tokenServices"
    class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
    <property name="tokenStore" ref="tokenStore" />
    <property name="tokenEnhancer" ref="tokenEnhancer" />
    <property name="supportRefreshToken" value="true" />
    <property name="clientDetailsService" ref="clientDetails" />
</bean>

<bean id="tokenEnhancer"
    class="org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter" />

<bean id="requestFactory"
    class="org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory">
    <constructor-arg name="clientDetailsService" ref="clientDetails" />
</bean>

<bean id="approvalStore"
    class="org.springframework.security.oauth2.provider.approval.TokenApprovalStore">
    <property name="tokenStore" ref="tokenStore" />
</bean>

<oauth:authorization-server
    client-details-service-ref="clientDetails" token-services-ref="tokenServices">
    <oauth:client-credentials />
</oauth:authorization-server>

<oauth:resource-server id="resourceServerFilter" entry-point-ref="entry"
    resource-id="myprojectAssignment" token-services-ref="tokenServices" />

<bean id="entry" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
    <constructor-arg value="/myprojectassignment" />
</bean>

<oauth:client-details-service id="clientDetails">
    <oauth:client client-id=“client”
        authorized-grant-types="client_credentials" authorities="ROLE_CLIENT"
        scope="read,write" secret=“password” />
</oauth:client-details-service>

<mvc:default-servlet-handler />

<oauth:expression-handler id="oauthExpressionHandler" />

<oauth:web-expression-handler id="oauthWebExpressionHandler" />

<http pattern="/api/**"  
              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="/**"
                         access="IS_AUTHENTICATED_FULLY"/>

 <custom-filter ref="resourceServerFilter"
                         before="PRE_AUTH_FILTER" />
 <access-denied-handler ref="oauthAccessDeniedHandler" />


如前所述,为您的tokenStore创建您自己的
AuthenticationKeyGenerator