【问题标题】:Spring Security custom RememberMeAuthenticationFilter not getting firedSpring Security 自定义 RememberMeAuthenticationFilter 没有被解雇
【发布时间】:2014-05-05 00:03:17
【问题描述】:

我已经使用 Spring Security 3.1 在我的 Spring MVC 应用程序中实现了“记住我”功能

我的 security-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>

Filter 类是这样实现的:

    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 调试器中运行时我发现 HttpResponseAuthenticationFilter.onSuccessfulAuthentication() 没有被调用。

编辑

在修改了我的 security-context.xmls 并使用标准 Spring bean 定义了 remember-me 服务并在配置外观中引用该服务之后

    <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.springframework.security.authentication.RememberMeAuthenticationToken@303f2184: Principal: org.springframework.security.core.userdetails.User @cb7ea6f6:用户名:tarun4;密码保护];启用:真; AccountNonExpired:真;凭据非过期:真; AccountNonLocked:真;授予权限:ROLE_ADMIN,ROLE_USER;凭证:[受保护];已认证:真实;详细信息:org.springframework.security.web.authentication.WebAuthenticationDetails@b364:RemoteIpAddress:0:0:0:0:0:0:0:1;会话ID:空;授予权限:ROLE_ADMIN、ROLE_USER'*

所以看起来身份验证信息存在于会话中。

谢谢, 塔伦

【问题讨论】:

    标签: java spring spring-mvc spring-security


    【解决方案1】:

    remember-me 命名空间元素已插入 RememberMeAuthenticationFilter,因此它仍将优先于您的,因为它在过滤器链中位于它之前。

    如果您想使用自定义过滤器,您应该删除命名空间元素并为相关服务使用标准 Spring bean。有一个示例 in the reference manual (Section 11.4.1) 显示了所需的 bean。

    【讨论】:

    • 能否请您检查一下我所做的更改,看看现在看起来是否正常。进行上述更改后,我看到来自我添加的过滤器类的调试日志:'DEBUG: mypackage.HttpResponseAuthenticationFilter - SecurityContextHolder 未填充记住我的令牌'但我无法看到控件到达我的 onSuccessfulAuthentication 方法。
    • 这里也可能值得一提的是,在in the reference manual (Section 11.4.1) 中,RememberMeAuthenticationProvider 的包名被错误地提到为 org.springframework.security.authentication.rememberme.RememberMeAuthenticationProvider,正确的包名是 org.springframework。 security.authentication.RememberMeAuthenticationProvider
    • 请将完整的日志消息添加到您的问题中。令牌被拒绝或安全上下文已包含Authentication 对象(查看the code)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-28
    • 2015-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多