要求用户在密码到期后更改密码,但不能在会话期间更改密码

时间:2015-02-18 21:57:08

标签: java spring spring-security passwords j-security-check

目前,我的应用程序的逻辑是,当用户的密码在例如30天之后到期时,即使用户正在做某事,用户也将被重定向到“更改密码”屏幕。这是错的。只应在下次登录时提示用户更改密码。

我创建了一个CheckAfterLoginFilter,它扩展了逻辑所在的OncePerRequestFilter。但是,这会在每个请求中进行过滤,以便用户在会话中注销。如果可能的话,我不确定如何在这里实现所需的逻辑。

我的登录表单jsp使用j_security_check。我的第一个想法是将逻辑从CheckAfterLoginFilter移动到LoginController,但j_security_check似乎重定向到它自己的东西,我不知道或在哪里找到。

非常感谢一些帮助!

由于

2 个答案:

答案 0 :(得分:5)

当您使用Spring Security时,我假设您已经配置了authenticationManager,并且UserEntity实施了UserDetails

我的建议是提供自定义身份验证失败处理程序并覆盖UserEntity中的isCredentialsNonExpired()

这是一个示例(使用基于java的配置)。

自定义身份验证失败提供程序

@Bean
public AuthenticationFailureHandler customAuthenticationFailureHandler() {
    ExceptionMappingAuthenticationFailureHandler exceptionMappingAuthenticationFailureHandler =
            new ExceptionMappingAuthenticationFailureHandler();
    Map<Object, Object> map = new HashMap<>();
    map.put(
            "org.springframework.security.authentication.CredentialsExpiredException",
            "/resetPassword.html"
    );        

    exceptionMappingAuthenticationFailureHandler.setExceptionMappings(map);

    exceptionMappingAuthenticationFailureHandler.setRedirectStrategy(
            new RedirectStrategy() {
                @Override
                public void sendRedirect(
                        HttpServletRequest request, HttpServletResponse response, String url
                ) throws IOException {
                    response.sendRedirect(request.getContextPath() + url);
                }
            }
    );

    return exceptionMappingAuthenticationFailureHandler;
}

XML方式

<bean id="customAuthenticationFailureHandler" class="org.springframework.security.web.authentication.ExceptionMappingAuthenticationFailureHandler">
    <property name="exceptionMappings">
        <props>
            <prop key="org.springframework.security.authentication.CredentialsExpiredException">/change_password_page</prop>
        </props>
    </property>
    <property name="defaultFailureUrl" value="/resetPassword"/>
</bean>

并在您的security.xml中

<security:form-login ... authentication-failure-handler-ref="customAuthenticationFailureHandler">

最后在你的UserEntity

    @Override
    public boolean isCredentialsNonExpired() {
        if (// check password is expired or not) {
           return false;
        }
        return true;
     }

因此,当密码过期时,失败处理程序将重定向到您想要的页面。

答案 1 :(得分:0)

在签入servlet过滤器时允许有效期为31天,但登录时只有30天。

因此,当它在30天之后到达servlet过滤器时,它将继续运行至最后一天,但如果他们没有将密码更改31天,则无论如何都要将它们注销。