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

Ask user to change their password after their password expires, but not during their session

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

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

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

非常感谢您的帮助!

谢谢

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

因此,当它在 30 天后到达 servlet 过滤器时,它将继续运行直到另一天,但如果他们在 31 天内没有更改密码,您还是希望他们注销。

由于您正在使用 Spring 安全性,我假设您已经配置了 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;
     }

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