2014-03-26 48 views
0

我已經實現了 '記住我' 使用Spring安全在我的Spring MVC應用程序的功能3.1Spring Security的定製RememberMeAuthenticationFilter不被解僱

我的安全context.xml中看起來是這樣的:

<?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:security="http://www.springframework.org/schema/security" 
     xsi:schemaLocation="http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans.xsd 
       http://www.springframework.org/schema/security 
       http://www.springframework.org/schema/security/spring-security-3.1.xsd"> 

    <import resource="servlet-context.xml" /> 
    <security:global-method-security secured-annotations="enabled" /> 

    <security:http auto-config="true" authentication-manager-ref="am"> 

    <!-- Restrict URLs based on role --> 
    <security:intercept-url pattern="/public/**" access="IS_AUTHENTICATED_ANONYMOUSLY" /> 
    <security:intercept-url pattern="/resources/**" access="IS_AUTHENTICATED_ANONYMOUSLY" /> 
    <security:intercept-url pattern="/**" access="ROLE_USER" /> 

    <!-- Override default login and logout pages --> 
    <security:form-login login-page="/public/login" 
       login-processing-url="/public/loginProcess" 
       default-target-url="/public/loginSuccess" 
       authentication-failure-url="/public/login?login_error=1" 
       always-use-default-target="true" /> 
    <security:logout logout-url="/public/logout" logout-success-url="/public/login?logout=1" /> 
    <security:remember-me services-alias="rmService" data-source-ref="dataSource"/> 
    <security:custom-filter position="LAST" ref="httpResponseAuthFilter" /> 
    </security:http> 

    <security:authentication-manager id="am"> 
    <security:authentication-provider > 
     <security:password-encoder ref="passwordEncoder" /> 
     <security:jdbc-user-service data-source-ref="dataSource" /> 
    </security:authentication-provider> 
    </security:authentication-manager> 

    <bean id="httpResponseAuthFilter" 
    class="mypackage.HttpResponseAuthenticationFilter" > 
    <property name="authenticationManager" ref="am"/> 
    <property name="rememberMeServices" ref="rmService"></property> 
    </bean> 

</beans> 

過濾器類是這樣實現的:

public class HttpResponseAuthenticationFilter extends RememberMeAuthenticationFilter { 

    @Override 
    protected void onSuccessfulAuthentication(final HttpServletRequest request, final HttpServletResponse response, 
      final Authentication authResult) { 

     super.onSuccessfulAuthentication(request, response, authResult); 

     if (authResult != null) { 
      // process post authentication logic here.. 
     } 
    } 

} 

記住我的功能工作正常使用上述配置,但在eclipse中運行deb ugger我發現HttpResponseAuthenticationFilter.onSuccessfulAuthentication()不會被調用。

編輯

修改我的安全,context.xmls並使用標準的Spring bean定義記得我服務和引用服務裏面的配置後看起來

<security:http auto-config="true" authentication-manager-ref="am"> 
    <!-- Restrict URLs based on role --> 
    <security:intercept-url pattern="/public/**" access="IS_AUTHENTICATED_ANONYMOUSLY" /> 
    <security:intercept-url pattern="/resources/**" access="IS_AUTHENTICATED_ANONYMOUSLY" /> 
    <security:intercept-url pattern="/**" access="ROLE_USER" /> 

    <!-- Override default login and logout pages --> 
    <security:form-login login-page="/public/login" 
         login-processing-url="/public/loginProcess" 
         default-target-url="/public/loginSuccess" 
         authentication-failure-url="/public/login?login_error=1" 
         always-use-default-target="true" /> 

    <security:remember-me services-ref="rememberMeService"/> 
    <security:logout logout-url="/public/logout" logout-success-url="/public/login?logout=1" /> 
    <security:custom-filter position="LAST" ref="httpResponseAuthFilter" /> 
</security:http> 

<security:authentication-manager id="am"> 
    <security:authentication-provider > 
     <security:password-encoder ref="passwordEncoder" /> 
     <security:jdbc-user-service data-source-ref="dataSource" /> 
    </security:authentication-provider> 
    <security:authentication-provider ref="rememberMeAuthenticationProvider" /> 
</security:authentication-manager> 

<bean id="rememberMeAuthenticationProvider" class= 
     "org.springframework.security.authentication.RememberMeAuthenticationProvider"> 
     <property name="key" value="riskAnalysis" /> 
</bean> 

<bean id="httpResponseAuthFilter" 
    class="mypacakge.HttpResponseAuthenticationFilter" > 
    <property name="authenticationManager" ref="am"/> 
    <property name="rememberMeServices" ref="rememberMeService"></property> 
</bean> 

<bean id="rememberMeService" 
    class="org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices"> 
    <property name="userDetailsService" ref="userDetailsService" /> 
    <property name="key" value="riskAnalysis" /> 
</bean> 

<bean id="userDetailsService" 
    class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl"> 
    <property name="dataSource" ref="dataSource"/> 
</bean>  

這裏是我所得到的在日誌中:

* DEBUG:mypackage.HttpResponseAuthenticationFilter - SecurityContextHolder沒有填入記憶我標記,因爲它已經包含:'org.springframew [email protected]84:委託人:[email protected]:用戶名:tarun4;密碼保護];啓用:true; AccountNonExpired:true; credentialsNonExpired:true; AccountNonLocked:true;授予權限:ROLE_ADMIN,ROLE_USER;證書:[PROTECTED];已驗證:true;詳細信息:org.sprin[email protected]b364:RemoteIpAddress:0:0:0:0:0:0:0:1; SessionId:null;授予權限:ROLE_ADMIN,ROLE_USER'*

因此它看起來像會話中存在認證信息。

感謝, 塔倫

回答

2

remember-me命名空間元素已經插入RememberMeAuthenticationFilter所以它仍然會優先於你的,因爲它在過濾器鏈來之前它。

如果您想使用自定義過濾器,您應該刪除命名空間元素併爲相關服務使用標準Spring bean。有一個例子in the reference manual (Section 11.4.1),它顯示了所需的bean。

+0

請您檢查我所做的更改,看看現在是否看起來不錯。進行上述更改後,我看到我添加的Filter類中的調試日誌:'DEBUG:mypackage.HttpResponseAuthenticationFilter - SecurityContextHolder未填充記住我的令牌' 但我一直無法看到控制權到達我的onSuccessfulAuthentication方法。 –

+0

也可能值得一提的是在[參考手冊(第11.4.1節)](http://docs.spring.io/spring-security/site/docs/3.1.x/reference/springsecurity-single .html#remember-me-impls)RememberMeAuthenticationProvider的軟件包名稱被錯誤地提及爲org.springframework.security.authentication.rememberme.RememberMeAuthenticationProvider,正確的軟件包名稱是org.springframework.security.authentication.RememberMeAuthenticationProvider –

+0

請添加完整日誌留言給你的問題。無論是令牌被拒絕還是安全上下文已經包含一個'Authentication'對象(看看[代碼](https:// github。COM /彈簧項目/彈簧安全/ BLOB /主機/網絡/ src目錄/主/ JAVA /組織/ springframework的/安全/網絡/認證/與rememberMe/RememberMeAuthenticationFilter.java#L142))。 –