spring security oauth2(2.0.8)获取InMemory令牌库使用的无效访问令牌

时间:2016-01-27 07:20:52

标签: java spring-mvc spring-security oauth-2.0 spring-security-oauth2

尝试在我的应用程序中实现spring security oauth2。

我可以使用以下方式获取访问令牌和刷新令牌:

  

http://localhost:8080/xApp/oauth/token?username=user1&password=password&grant_type=password&client_id=xApp&client_secret=xApp

     

{   “access_token”:“798c7e71-983b-4137-a0cb-ceae4e9b4190”   “token_type”:“bearer”   “refresh_token”:“0752b8ff-5086-4457-918d-54376c7a2bec”   “expires_in”:299   “范围”:“读信任写”   }

当我尝试使用以下网址

访问受保护资源时
  

http://localhost:8080/xapp/data/product/api/index/?access_token=798c7e71-983b-4137-a0cb-ceae4e9b4190

我收到了:

  

{   “错误”:“invalid_token”   “error_description”:“无效的访问令牌:db48214c-04d7-4d6b-aa34-6d16c9c2a438”   }

applicationContext-security.xml:

 <?xml version="1.0" encoding="UTF-8"?>
    <beans:beans 
    xmlns="http://www.springframework.org/schema/security" 
    xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:oauth="http://www.springframework.org/schema/security/oauth2"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                       http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd 
                       http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2.xsd">

      <http pattern="/login*" security="none" />


      <http pattern="/*.html" security="none" />
      <http pattern="/*.pdf" security="none" />
      <http pattern="/*.xls" security="none" />
      <http pattern="/cache-viewer.jnlp" security="none" />
      <!-- /old documentation URLs -->

      <!-- servlets -->
      <http pattern="/Index" security="none" />
    <http pattern="/ServletRedirector" security="none" />

    <!-- This is where we tells spring security what URL should be protected 
        and what roles have access to them -->
    <http pattern="/data/**" entry-point-ref="oauthAuthenticationEntryPoint"
        create-session="never" xmlns="http://www.springframework.org/schema/security"
        use-expressions="true">
        <anonymous enabled="false" />       
        <access-denied-handler ref="oauthAccessDeniedHandler" />
        <custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
    </http> 

    <http pattern="/oauth/token" create-session="stateless"
        use-expressions="true">
        <!--  authentication-manager-ref="clientAuthenticationManager"  -->
        <intercept-url pattern="/oauth/token" access="hasRole('Administrator')" />
        <anonymous enabled="false" />
        <custom-filter ref="clientCredentialsTokenEndpointFilter"
            after="BASIC_AUTH_FILTER" />
        <access-denied-handler ref="oauthAccessDeniedHandler" />
        <http-basic entry-point-ref="clientAuthenticationEntryPoint" />
        </http>

     <http use-expressions="true" disable-url-rewriting="true" entry-point-ref="authenticationChooser">
      <!-- /servlets -->
      <intercept-url pattern="/**" access="isAuthenticated()" />
      <intercept-url pattern="/" access="isAuthenticated()" />
      <form-login login-page="/login" authentication-failure-url="/login?login_error=1" authentication-success-handler-ref="authSuccessHandler"/>
      <logout logout-url="/logout" logout-success-url="/login" />
      <remember-me key="XappWebClient" services-ref="rememberMeServices" />
      <custom-filter ref="jbossSecurityFilter" after="REMEMBER_ME_FILTER" />
      </http>

    <beans:bean id="oauthAuthenticationEntryPoint"
        class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
        <beans:property name="realmName" value="Xapp" />
    </beans:bean>

    <beans:bean id="clientAuthenticationEntryPoint"
        class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
        <beans:property name="realmName" value="Xapp" />
        <beans:property name="typeName" value="Basic" />
    </beans:bean>

    <beans:bean id="oauthAccessDeniedHandler"
        class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" />

    <beans:bean id="clientCredentialsTokenEndpointFilter"
        class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
        <beans:property name="authenticationManager" ref="clientAuthenticationManager" />
    </beans:bean>   


    <beans:bean id="accessDecisionManager" class="org.springframework.security.access.vote.UnanimousBased"
          xmlns="http://www.springframework.org/schema/beans">
        <beans:constructor-arg>
            <beans:list>
                <beans:bean class="org.springframework.security.oauth2.provider.vote.ScopeVoter"/>
                <beans:bean class="org.springframework.security.access.vote.RoleVoter"/>
                <beans:bean class="org.springframework.security.access.vote.AuthenticatedVoter"/>
            </beans:list>
        </beans:constructor-arg>
    </beans:bean>

    <authentication-manager id="clientAuthenticationManager"
        xmlns="http://www.springframework.org/schema/security">
        <authentication-provider user-service-ref="clientDetailsUserService" />
    </authentication-manager>

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

    <!-- This defined token store, we have used inmemory tokenstore for now 
        but this can be changed to a user defined one -->
    <beans:bean id="tokenStore"
        class="org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore" />

    <!-- This is where we defined token based configurations, token validity 
        and other things -->  
    <beans:bean id="tokenServices"
        class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
        <beans:property name="tokenStore" ref="tokenStore" />
        <beans:property name="supportRefreshToken" value="true" />
        <beans:property name="accessTokenValiditySeconds" value="300000"/>
        <beans:property name="clientDetailsService" ref="clientDetails" />
    </beans:bean>

    <beans:bean id="userApprovalHandler"
        class="org.springframework.security.oauth2.provider.approval.TokenStoreUserApprovalHandler">
        <beans:property name="tokenStore" ref="tokenStore" />
        <beans:property name="requestFactory" ref="oAuth2RequestFactory" />
    </beans:bean>

    <beans:bean id="oAuth2RequestFactory"
        class="org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory">
        <beans:constructor-arg ref="clientDetails" />
    </beans:bean>

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

       <!-- OAuth2 Authorization Server -->
    <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 authentication-manager-ref="authenticationManager"/>
    </oauth:authorization-server>

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

    <oauth:client-details-service id="clientDetails">
        <!-- client -->     
        <oauth:client client-id="Xapp"
            authorized-grant-types="password,authorization_code,refresh_token,implicit"
            secret="Xapp" scope="read,write,trust" authorities="Administrator" access-token-validity="300" refresh-token-validity="600"/>

    </oauth:client-details-service>

   <authentication-manager alias="authenticationManager">
      <authentication-provider ref="jaasAuthenticationProvider"/>
   </authentication-manager>

   <beans:bean id="rememberMeServices"
      class="com.Xapp.Xapp.web.authentication.rememberme.RememberMeServices">
      <beans:property name="userDetailsService" ref="userDetailsService" />
      <beans:property name="key" value="XappWebClient" />
   </beans:bean>

   <beans:bean id="jaasNameCallBackHandler" 
      class="com.Xapp.Xapp.web.authentication.XappNameCallbackHandler">
      <beans:property name="userDetailsService" ref="userDetailsService" />
      <beans:property name="callbackHandler">
         <beans:bean class="org.springframework.security.authentication.jaas.JaasNameCallbackHandler"/>
      </beans:property>
   </beans:bean>

   <beans:bean id="jaasAuthenticationProvider" 
      class="org.springframework.security.authentication.jaas.JaasAuthenticationProvider">
      <beans:property name="refreshConfigurationOnStartup" value="false"/> 
      <beans:property name="loginConfig" value="/WEB-INF/login.conf" />
      <beans:property name="loginContextName" value="Xapp" />
      <beans:property name="callbackHandlers">
         <beans:list>
            <beans:ref bean="jaasNameCallBackHandler" />
            <beans:bean class="org.springframework.security.authentication.jaas.JaasPasswordCallbackHandler" />
         </beans:list>
      </beans:property>
      <beans:property name="authorityGranters">
         <beans:list>
            <beans:bean class="com.Xapp.Xapp.web.authentication.XappAuthorityGranter" />
         </beans:list>
      </beans:property>
   </beans:bean>

   <beans:bean id="userDetailsService" class="com.Xapp.Xapp.web.authentication.XappUserDetailsService">
   </beans:bean>

   <beans:bean id="jbossSecurityFilter" class="com.Xapp.Xapp.web.authentication.JBossSecurityFilter">
      <beans:property name="clientLoginDomain" value="client-login" />
      <beans:property name="callbackHandler">
         <beans:bean class="com.Xapp.Xapp.web.authentication.SecurityContextHolderAwareCallbackHandler" />
      </beans:property>
   </beans:bean>

   <beans:bean id="authSuccessHandler"
      class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
      <beans:property name="redirectStrategy" ref="XappRedirectStrategy"></beans:property>
   </beans:bean>

   <beans:bean id="XappRedirectStrategy"
      class="com.Xapp.Xapp.web.authentication.XappRedirectStrategy">
   </beans:bean>

   <beans:bean id="formAuthenticationEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
      <beans:property name="loginFormUrl" value="/login" />
   </beans:bean>

   <beans:bean id="authenticationChooser" class="org.springframework.security.web.authentication.DelegatingAuthenticationEntryPoint">
      <beans:constructor-arg>
         <beans:map>
             <beans:entry key="#{new com.Xapp.Xapp.web.authentication.DataRequestMatcher()}" value-ref="oauthAuthenticationEntryPoint" />
         </beans:map>
      </beans:constructor-arg>
      <beans:property name="defaultEntryPoint" ref="formAuthenticationEntryPoint" />
   </beans:bean>
</beans:beans>

控制器类路径:

@Controller
@RequestMapping("/data/product")
public final class AppController extends AbstractDataController {

@RequestMapping(value = "/index", method = RequestMethod.GET)
@ResponseBody public List<Data> getProducts() throws ServerException  {
  final List<DataTO> dataTOs = productLogic.findDataTOsForCurrentUser();
  Collections.sort(dataTOs, HasName.COMPARATOR);
  return ListConverter.convert(dataTOs, fromDataTO);
 }
}

调试第二个请求时的堆栈跟踪accessTokenStore未存储访问令牌为空:

2016-02-02 11:11:16,268 DEBUG [org.springframework.security.web.context.HttpSessionSecurityContextRepository] (default task-3) HttpSession returned null object for SPRING_SECURITY_CONTEXT
2016-02-02 11:11:16,269 DEBUG [org.springframework.security.web.context.HttpSessionSecurityContextRepository] (default task-3) No SecurityContext was available from the HttpSession: io.undertow.servlet.spec.HttpSessionImpl@4439d585. A new one will be created.
2016-02-02 11:11:16,315 DEBUG [org.springframework.security.web.FilterChainProxy] (default task-3) /data/product/index at position 2 of 10 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2016-02-02 11:11:16,315 DEBUG [org.springframework.security.web.FilterChainProxy] (default task-3) /data/product/index at position 3 of 10 in additional filter chain; firing Filter: 'OAuth2AuthenticationProcessingFilter'
2016-02-02 11:11:16,315 DEBUG [org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationProcessingFilter] (default task-3) Entering Do filter>>>>>>>>>>>>>>>>>>>>
2016-02-02 11:11:16,316 DEBUG [org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationProcessingFilter] (default task-3) !!!!!!!!!!request>>>>>>>>> org.springframework.security.web.context.HttpSessionSecurityContextRepository$Servlet3SaveToSessionRequestWrapper@590ca42d
2016-02-02 11:11:16,317 DEBUG [org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationProcessingFilter] (default task-3) !!!!!!!!!!authentication>>>>>>>>> org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken@763c08a: Principal: 34a81f49-528d-4087-b192-414b6e2224b6; Credentials: [PROTECTED]; Authenticated: false; Details: remoteAddress=127.0.0.1, sessionId=<SESSION>, tokenType=BearertokenValue=<TOKEN>; Not granted any authorities
2016-02-02 11:11:16,317 DEBUG [org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationManager] (default task-3) >>>Call authenticate>>>> token 34a81f49-528d-4087-b192-414b6e2224b6
2016-02-02 11:11:16,317 DEBUG [org.springframework.security.oauth2.provider.token.DefaultTokenServices] (default task-3) >>>>>>accessTokenValue>>>>>>>>>>>>>>> 34a81f49-528d-4087-b192-414b6e2224b6
2016-02-02 11:11:16,317 DEBUG [org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore] (default task-3) >>>>MAP>>>>>>>{}
2016-02-02 11:11:16,317 DEBUG [org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationProcessingFilter] (default task-3) <<<<<<<<<<<Trace Error>>>>>>>>>>>>>>>>>>
2016-02-02 11:11:16,339 ERROR [stderr] (default task-3) error="invalid_token", error_description="Invalid access token: 34a81f49-528d-4087-b192-414b6e2224b6"

2016-02-02 11:11:16,339 ERROR [stderr] (default task-3)     at org.springframework.security.oauth2.provider.token.DefaultTokenServices.loadAuthentication(DefaultTokenServices.java:237)

2016-02-02 11:11:16,340 ERROR [stderr] (default task-3)     at org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationManager.authenticate(OAuth2AuthenticationManager.java:88)

2016-02-02 11:11:16,340 ERROR [stderr] (default task-3)     at org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationProcessingFilter.doFilter(OAuth2AuthenticationProcessingFilter.java:152)

2016-02-02 11:11:16,340 ERROR [stderr] (default task-3)     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)

2016-02-02 11:11:16,340 ERROR [stderr] (default task-3)     at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)

2016-02-02 11:11:16,340 ERROR [stderr] (default task-3)     at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)

2016-02-02 11:11:16,340 ERROR [stderr] (default task-3)     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)

2016-02-02 11:11:16,340 ERROR [stderr] (default task-3)     at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)

2016-02-02 11:11:16,340 ERROR [stderr] (default task-3)     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)

2016-02-02 11:11:16,340 ERROR [stderr] (default task-3)     at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)

可能与Oauth2: Invalid access token重复,但未得到答复。尝试堆栈中的其他链接无法解决我的问题。有关配置OAuth2 Spring security 2.0.8的任何帮助或建议都会很棒。

我们可以使用JDBCtokenstore和jwttokenstore进行配置,如下面的答案所示,但仍然无法使用InMemorystore对此有任何帮助!!!

2 个答案:

答案 0 :(得分:1)

从资源API看起来,您在请求参数中传递了access_token。您必须在请求标头中传递access_token,如下所示:

Authorization: Bearer <access_token>

cURL示例:

curl -X GET -H "Authorization: Bearer 89af6541-f87f-4c63-be6d-6012426bb745" -H "Cache-Control: no-cache" "http://localhost:8080/xapp/data/product/api/index"

答案 1 :(得分:0)

解决无效访问令牌:

  1. 我们将存储类型从InMemory更改为数据库存储(JdbcTokenStore)。

    为所有http标签添加了rememberMeServices,其中应在applicationContext-security.xml中保护spring安全URL。

    <remember-me key="xAppWebClient" services-ref="rememberMeServices" />
    <custom-filter ref="jbossSecurityFilter" after="REMEMBER_ME_FILTER" />
    
  2. applicationContext-security.xml更改:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans:beans 
       xmlns="http://www.springframework.org/schema/security" 
       xmlns:beans="http://www.springframework.org/schema/beans"
       xmlns:oauth="http://www.springframework.org/schema/security/oauth2"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                           http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd 
                           http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2.xsd">
    
          <http pattern="/Index" security="none" />
    
        <!--This is where we tells spring security what URL should be protected 
            and what roles have access to them -->
    
        <http pattern="/data/**" entry-point-ref="oauthAuthenticationEntryPoint"
            create-session="never" xmlns="http://www.springframework.org/schema/security"
            use-expressions="true">
            <anonymous enabled="false" />       
            <access-denied-handler ref="oauthAccessDeniedHandler" />    
            <intercept-url pattern="/data/**" access="isAuthenticated()" />         
            <remember-me key="XappWebClient" services-ref="rememberMeServices" />
            <custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
          <custom-filter ref="jbossSecurityFilter" after="REMEMBER_ME_FILTER" />
        </http> 
    
        <http pattern="/oauth/token" create-session="stateless"
            use-expressions="true" authentication-manager-ref="authenticationManager">
            <intercept-url pattern="/oauth/token" access="isAuthenticated()" />
            <anonymous enabled="false" />
            <custom-filter ref="clientCredentialsTokenEndpointFilter"
                before="BASIC_AUTH_FILTER" />
            <access-denied-handler ref="oauthAccessDeniedHandler" />
            <http-basic entry-point-ref="clientAuthenticationEntryPoint" />
            <remember-me key="XappWebClient" services-ref="rememberMeServices" />
          <custom-filter ref="jbossSecurityFilter" after="REMEMBER_ME_FILTER" />
        </http>
    
       <http use-expressions="true" disable-url-rewriting="true" entry-point-ref="authenticationChooser">
          <!-- /servlets -->      
          <intercept-url pattern="/**" access="isAuthenticated()" />
          <intercept-url pattern="/" access="isAuthenticated()" />
          <form-login login-page="/login" authentication-failure-url="/login?login_error=1" authentication-success-handler-ref="authSuccessHandler"/>
          <logout logout-url="/logout" logout-success-url="/login" />
          <remember-me key="XappWebClient" services-ref="rememberMeServices" />
          <custom-filter ref="jbossSecurityFilter" after="REMEMBER_ME_FILTER" />
       </http>
    
        <beans:bean id="oauthAuthenticationEntryPoint"
            class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
            <beans:property name="realmName" value="Xapp" />
        </beans:bean>
    
        <beans:bean id="clientAuthenticationEntryPoint"
            class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">      
            <beans:property name="typeName" value="Basic" />
        </beans:bean>
    
        <beans:bean id="oauthAccessDeniedHandler"
            class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" />
    
        <beans:bean id="clientCredentialsTokenEndpointFilter"
            class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
            <beans:property name="authenticationManager" ref="authenticationManager" />
        </beans:bean>   
    
        <beans:bean id="accessDecisionManager" class="org.springframework.security.access.vote.UnanimousBased"
              xmlns="http://www.springframework.org/schema/beans">
            <beans:constructor-arg>
                <beans:list>
                    <beans:bean class="org.springframework.security.oauth2.provider.vote.ScopeVoter"/>
                    <beans:bean class="org.springframework.security.access.vote.RoleVoter"/>
                    <beans:bean class="org.springframework.security.access.vote.AuthenticatedVoter"/>
                </beans:list>
            </beans:constructor-arg>
        </beans:bean>
    
        <beans:bean id="clientDetailsUserService"
            class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
            <beans:constructor-arg ref="clientDetails" />
        </beans:bean>
    
        <!-- This defined token store, we have used JdbcTokenStore insted of inmemory tokenstore-->
        <beans:bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.store.JdbcTokenStore">
            <beans:constructor-arg name="dataSource" ref="dataSource" />
        </beans:bean>
    
        <beans:bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
            <beans:property name="jndiName">
                <beans:value>jdbc/XappDS</beans:value>
            </beans:property>
        </beans:bean>
    
        <!-- This is where we defined token based configurations, token validity 
            and other things -->  
        <beans:bean id="tokenServices"
            class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
            <beans:property name="tokenStore" ref="tokenStore" />
            <beans:property name="supportRefreshToken" value="true" />
            <beans:property name="clientDetailsService" ref="clientDetails" />
        </beans:bean>
    
        <beans:bean id="userApprovalHandler"
            class="org.springframework.security.oauth2.provider.approval.TokenStoreUserApprovalHandler">
            <beans:property name="tokenStore" ref="tokenStore" />
            <beans:property name="requestFactory" ref="oAuth2RequestFactory" />
        </beans:bean>
    
        <beans:bean id="oAuth2RequestFactory"
            class="org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory">
            <beans:constructor-arg ref="clientDetails" />
        </beans:bean>
    
        <beans:bean id="approvalStore" class="org.springframework.security.oauth2.provider.approval.TokenApprovalStore">
            <beans:property name="tokenStore" ref="tokenStore"/>
        </beans:bean>
    
           <!-- OAuth2 Authorization Server -->
        <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 authentication-manager-ref="authenticationManager"/>
        </oauth:authorization-server>
    
        <oauth:resource-server id="resourceServerFilter"
             token-services-ref="tokenServices" />
    
        <oauth:client-details-service id="clientDetails">
            <oauth:client client-id="Xapp"
                authorized-grant-types="password,authorization_code,refresh_token,implicit"
                secret="Xapp" scope="read,write,trust" authorities="Administrator" access-token-validity="300" refresh-token-validity="600"/>   
        </oauth:client-details-service>
    
        <authentication-manager  alias="authenticationManager">
        <authentication-provider ref="jaasAuthenticationProvider" />
        <authentication-provider user-service-ref="clientDetailsUserService"/>
        </authentication-manager>
    
       <beans:bean id="rememberMeServices"
          class="com.Xapp.Xapp.web.authentication.rememberme.RememberMeServices">
          <beans:property name="userDetailsService" ref="userDetailsService" />
          <beans:property name="key" value="XappWebClient" />
       </beans:bean>
    
       <beans:bean id="jaasNameCallBackHandler" 
          class="com.Xapp.Xapp.web.authentication.XappNameCallbackHandler">
          <beans:property name="userDetailsService" ref="userDetailsService" />
          <beans:property name="callbackHandler">
             <beans:bean class="org.springframework.security.authentication.jaas.JaasNameCallbackHandler"/>
          </beans:property>
       </beans:bean>
    
       <beans:bean id="jaasAuthenticationProvider" 
          class="org.springframework.security.authentication.jaas.JaasAuthenticationProvider">
          <beans:property name="refreshConfigurationOnStartup" value="false"/> 
          <beans:property name="loginConfig" value="/WEB-INF/login.conf" />
          <beans:property name="loginContextName" value="Xapp" />
          <beans:property name="callbackHandlers">
             <beans:list>
                <beans:ref bean="jaasNameCallBackHandler" />
                <beans:bean class="org.springframework.security.authentication.jaas.JaasPasswordCallbackHandler" />
             </beans:list>
          </beans:property>
          <beans:property name="authorityGranters">
             <beans:list>
                <beans:bean class="com.Xapp.Xapp.web.authentication.XappAuthorityGranter" />
             </beans:list>
          </beans:property>
       </beans:bean>
    
       <beans:bean id="userDetailsService" class="com.Xapp.Xapp.web.authentication.XappUserDetailsService">
       </beans:bean>
    
       <beans:bean id="jbossSecurityFilter" class="com.Xapp.Xapp.web.authentication.JBossSecurityFilter">
          <beans:property name="clientLoginDomain" value="client-login" />
          <beans:property name="callbackHandler">
             <beans:bean class="com.Xapp.Xapp.web.authentication.SecurityContextHolderAwareCallbackHandler" />
          </beans:property>
       </beans:bean>
    
       <beans:bean id="authSuccessHandler"
          class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
          <beans:property name="redirectStrategy" ref="XappRedirectStrategy"></beans:property>
       </beans:bean>
    
       <beans:bean id="XappRedirectStrategy"
          class="com.Xapp.Xapp.web.authentication.XappRedirectStrategy">
       </beans:bean>
    
       <beans:bean id="formAuthenticationEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
          <beans:property name="loginFormUrl" value="/login" />
       </beans:bean>
    
       <beans:bean id="authenticationChooser" class="org.springframework.security.web.authentication.DelegatingAuthenticationEntryPoint">
          <beans:constructor-arg>
             <beans:map>
                 <beans:entry key="#{new com.Xapp.Xapp.web.authentication.DataRequestMatcher()}" value-ref="oauthAuthenticationEntryPoint" />
             </beans:map>
          </beans:constructor-arg>
          <beans:property name="defaultEntryPoint" ref="formAuthenticationEntryPoint" />
       </beans:bean>
    </beans:beans> 
    
    1. 我们尝试的另一种方法是使用JwtTokenStore,它是内存的绝佳替代品。配置如xml:

        <http pattern="/login*" security="none" />
        <http pattern="/*.html" security="none" />
        <http pattern="/*.pdf" security="none" />
        <http pattern="/Index" security="none" />
      
      <!-- This is where we tells spring security what URL should be protected 
          and what roles have access to them -->
      <http pattern="/restdata/**" entry-point-ref="oauthAuthenticationEntryPoint"
          create-session="stateless" xmlns="http://www.springframework.org/schema/security"
          use-expressions="true">
          <anonymous enabled="false" />
          <access-denied-handler ref="oauthAccessDeniedHandler" />
          <intercept-url pattern="/restdata/**" access="isAuthenticated()" />
          <remember-me key="XappWebClient" services-ref="rememberMeServices" />
          <custom-filter ref="jbossSecurityFilter" after="REMEMBER_ME_FILTER" />
          <custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
      </http>
      
      <http pattern="/oauth/token" create-session="stateless"
          use-expressions="true" authentication-manager-ref="authenticationManager">
          <intercept-url pattern="/oauth/token" access="isAuthenticated()" />
          <anonymous enabled="false" />
          <custom-filter ref="clientCredentialsTokenEndpointFilter"
              before="BASIC_AUTH_FILTER" />
          <access-denied-handler ref="oauthAccessDeniedHandler" />
          <http-basic entry-point-ref="clientAuthenticationEntryPoint" />
          <remember-me key="XappWebClient" services-ref="rememberMeServices" />
          <custom-filter ref="jbossSecurityFilter" after="REMEMBER_ME_FILTER" />
      </http>
      
      <http use-expressions="true" disable-url-rewriting="true"
          entry-point-ref="authenticationChooser">
          <intercept-url pattern="/**" access="isAuthenticated()" />
          <intercept-url pattern="/" access="isAuthenticated()" />
          <form-login login-page="/login" authentication-failure-url="/login?login_error=1"
              authentication-success-handler-ref="authSuccessHandler" />
          <logout logout-url="/logout" logout-success-url="/login" />
          <remember-me key="XappWebClient" services-ref="rememberMeServices" />
          <custom-filter ref="jbossSecurityFilter" after="REMEMBER_ME_FILTER" />
          <custom-filter ref="myFilter" position="PRE_AUTH_FILTER" /> <!--Custom filter intercepts the login request from web client and authorize the user using oauth token request-->
      </http>
      
      <beans:bean id="myFilter"
          class="com.Xapp.Xapp.web.authentication.XappPreAuthenticationFilter">
          <beans:property name="authenticationManager" ref="authenticationManager" />
      </beans:bean>
      
      <beans:bean id="oauthAuthenticationEntryPoint"
          class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
          <beans:property name="realmName" value="Xapp" />
      </beans:bean>
      
      <beans:bean id="clientAuthenticationEntryPoint"
          class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
          <!--  <beans:property name="realmName" value="Xapp" /> -->
          <beans:property name="typeName" value="Basic" />
      </beans:bean>
      
      <beans:bean id="oauthAccessDeniedHandler"
          class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" />
      
      <beans:bean id="clientCredentialsTokenEndpointFilter"
          class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
          <beans:property name="authenticationManager" ref="authenticationManager" />
      </beans:bean>   
      
      <beans:bean id="accessDecisionManager" class="org.springframework.security.access.vote.UnanimousBased"
            xmlns="http://www.springframework.org/schema/beans">
          <beans:constructor-arg>
              <beans:list>
                  <beans:bean class="org.springframework.security.oauth2.provider.vote.ScopeVoter"/>
                  <beans:bean class="org.springframework.security.access.vote.RoleVoter"/>
                  <beans:bean class="org.springframework.security.access.vote.AuthenticatedVoter"/>
              </beans:list>
          </beans:constructor-arg>
      </beans:bean>
      
      <beans:bean id="clientDetailsUserService"
          class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
          <beans:constructor-arg ref="clientDetails" />
      </beans:bean>
      
      <beans:bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.store.JwtTokenStore">
          <beans:constructor-arg ref="jwtTokenEnhancer" />
      </beans:bean>
      
      <beans:bean id="jwtTokenEnhancer" class="org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter">
          <beans:property name="signingKey" value="Xapp" />
          <beans:property name="accessTokenConverter" ref="tokenConverter" />
      </beans:bean>   
      
      <!-- define token based configurations, token validity and other things -->  
      <beans:bean id="tokenServices"
          class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
          <beans:property name="tokenStore" ref="tokenStore" />
          <beans:property name="supportRefreshToken" value="true" />
          <beans:property name="clientDetailsService" ref="clientDetails" />
          <beans:property name="tokenEnhancer" ref="jwtTokenEnhancer" />
      </beans:bean>
      
      <beans:bean id="userApprovalHandler"
          class="org.springframework.security.oauth2.provider.approval.TokenStoreUserApprovalHandler">
          <beans:property name="tokenStore" ref="tokenStore" />
          <beans:property name="requestFactory" ref="oAuth2RequestFactory" />
      </beans:bean>
      
      <beans:bean id="oAuth2RequestFactory"
          class="org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory">
          <beans:constructor-arg ref="clientDetails" />
      </beans:bean>
      
      <beans:bean id="approvalStore" class="org.springframework.security.oauth2.provider.approval.TokenApprovalStore">
          <beans:property name="tokenStore" ref="tokenStore"/>
      </beans:bean>
      
         <!-- OAuth2 Authorization Server -->
      <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 authentication-manager-ref="authenticationManager"/>
      </oauth:authorization-server>
      
      <oauth:resource-server id="resourceServerFilter"
           token-services-ref="tokenServices" />
      
      <oauth:client-details-service id="clientDetails">
          <!-- client -->
          <oauth:client client-id="Xapp"
              authorized-grant-types="password,authorization_code,refresh_token"
              secret="Xapp" scope="read,write,trust" authorities="Administrator"/>
      </oauth:client-details-service>
      
      <global-method-security
          pre-post-annotations="enabled" proxy-target-class="true">
          <expression-handler ref="oauthExpressionHandler" />
      </global-method-security>
      
      <oauth:expression-handler id="oauthExpressionHandler" />
      <oauth:web-expression-handler id="oauthWebExpressionHandler" />
      
      <authentication-manager  alias="authenticationManager">
          <authentication-provider ref="jaasAuthenticationProvider" />
          <authentication-provider user-service-ref="clientDetailsUserService"/>
      </authentication-manager>