Spring Security custom RememberMeAuthenticationFilter not getting fired

ぃ、小莉子 提交于 2021-02-20 04:18:50

问题


I have implemented 'Remember Me' functionality in my Spring MVC application using Spring Security 3.1

My security-context.xml looks like this :

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

The Filter class is implemented like this :

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

}

Remember me functionality works fine using the above configuration but while running in eclipse debugger I found that HttpResponseAuthenticationFilter.onSuccessfulAuthentication() doesn't get invoked.

EDIT

After modifying my security-context.xmls and defining the remember-me service using standard Spring beans and referencing the service inside the configuration looks

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

Here is what I get in the logs :

*DEBUG: mypackage.HttpResponseAuthenticationFilter - SecurityContextHolder not populated with remember-me token, as it already contained: 'org.springframework.security.authentication.RememberMeAuthenticationToken@303f2184: Principal: org.springframework.security.core.userdetails.User@cb7ea6f6: Username: tarun4; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN,ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ADMIN, ROLE_USER'*

So it looks like authentication information is present in the session.

Thanks, Tarun


回答1:


The remember-me namespace element already inserts a RememberMeAuthenticationFilter so it will still take precedence over yours, since it comes before it in the filter chain.

If you want to use a custom filter, you should remove the namespace element and use standard Spring beans for the related services. There's an example in the reference manual (Section 11.4.1) which shows the beans needed.



来源:https://stackoverflow.com/questions/22663488/spring-security-custom-remembermeauthenticationfilter-not-getting-fired

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!