问题 强制用户在spring security中更改过期密码


我正在构建基于网络的应用程序的spring mvc和spring security。

我已经实现了重置密码功能。系统管理员将重置任何用户的密码。随机生成的密码将通过电子邮件发送给用户,同样将在数据库中更新。

现在我希望每当用户使用随机生成的密码登录时,我想强制用户更改其密码。

请看看我的 用户 表。

userid bigint(20)
username varchar(20)
密码varchar(65)
email varchar(50)
firstname varchar(20)
lastname varchar(20)
groupname varchar(50)
启用tinyint(1)
credentialsNonExpired tinyint(1)

我的认证提供商

    <!--
        Configuring Authentication Provider to make use of spring security
        provided Jdbc user management service
    -->
    <authentication-provider user-service-ref="jdbcUserService">
        <!--
            Configuring SHA-1 Password Encoding scheme to secure user credential
        -->
        <password-encoder ref="sha1PasswordEncoder" />
    </authentication-provider>
</authentication-manager>

我用过 JDBCUserDetailsS​​ervice 扩展 JDBCDaoImpl 如 jdbcUserService

我想设置 credentialNonExpired 我重置密码时,我的用户表的错误列。

我能够做到这一点。

但是当我登录时,弹簧安全 JDBCuserdetailsservice loadUserbyUsername 只获取用户名,密码,已启用的列以及所有字段的其余部分设置为true。

protected List<UserDetails> loadUsersByUsername(String username) {
    return getJdbcTemplate().query(usersByUsernameQuery, new String[] {username}, new RowMapper<UserDetails>() {
        public UserDetails mapRow(ResultSet rs, int rowNum) throws SQLException {
            String username = rs.getString(1);
            String password = rs.getString(2);
            boolean enabled = rs.getBoolean(3);
            return new User(username, password, enabled, true, true, true, AuthorityUtils.NO_AUTHORITIES);
        }

    });
}

但我想要实际 credentialNonExpired 由重置密码设置的字段,以便spring安全性将抛出CREDENTIALEXPIREDEXCEPTION。

我通过加载上面的方法实现了这一点,但是当用密码过期登录时,是否还有其他方法可以重定向用户更改密码页面。

请告诉我该怎么做?


5895
2017-12-12 05:09


起源



答案:


很晚才回答,我不知道你是否使用Spring 2或3。 但是在Spring 3中你可以这样做。

在Spring安全上下文中包含以下内容:

<bean id="securityExceptionTranslationHandler" 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="/login_generic_error_page"/>
</bean>

当然,您可以将其他特定身份验证例外映射到其他页面。

如果您使用的是form-login元素,则必须指定 authentication-failure-handler-ref 属性(并删除 authentication-failure-url 如果使用)

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

最后一步是创建更改密码页面。

请记住,重定向到更改密码页面时,用户未经过身份验证。


15
2018-01-17 16:06



我正在研究一个非常类似的问题并沿着这条路走下去...是否有关于如何最好地处理更改密码逻辑的建议?似乎试图复制所有正常的“登录”功能(检查密码,填写SecurityContextHolder,返回错误代码)可能会变得棘手...... - bimsapi
我正在使用JPA和模型,我直接更新它们而不经历整个Spring安全周期。在我看来,这是最快的方式。当然,在更改密码后,我将用户重定向到登录页面。 - Adrian Ber
是的,我认为你的方式会更快:)这是我最终做的 - * UsernamePasswordResetAuthentication 使用用户名,密码和新密码*在适当的时候使用新/确认密码字段登录页面*根据请求创建正确的身份验证对象的登录过滤器*自定义身份验证提供者(由于各种原因已经存在),扩展为1)进行身份验证现有密码,2)更新存储的密码,3)用新密码重新验证。 - bimsapi
自定义身份验证提供程序是最重要的。但是如果你已经因为其他原因而已经有它... - Adrian Ber


答案:


很晚才回答,我不知道你是否使用Spring 2或3。 但是在Spring 3中你可以这样做。

在Spring安全上下文中包含以下内容:

<bean id="securityExceptionTranslationHandler" 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="/login_generic_error_page"/>
</bean>

当然,您可以将其他特定身份验证例外映射到其他页面。

如果您使用的是form-login元素,则必须指定 authentication-failure-handler-ref 属性(并删除 authentication-failure-url 如果使用)

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

最后一步是创建更改密码页面。

请记住,重定向到更改密码页面时,用户未经过身份验证。


15
2018-01-17 16:06



我正在研究一个非常类似的问题并沿着这条路走下去...是否有关于如何最好地处理更改密码逻辑的建议?似乎试图复制所有正常的“登录”功能(检查密码,填写SecurityContextHolder,返回错误代码)可能会变得棘手...... - bimsapi
我正在使用JPA和模型,我直接更新它们而不经历整个Spring安全周期。在我看来,这是最快的方式。当然,在更改密码后,我将用户重定向到登录页面。 - Adrian Ber
是的,我认为你的方式会更快:)这是我最终做的 - * UsernamePasswordResetAuthentication 使用用户名,密码和新密码*在适当的时候使用新/确认密码字段登录页面*根据请求创建正确的身份验证对象的登录过滤器*自定义身份验证提供者(由于各种原因已经存在),扩展为1)进行身份验证现有密码,2)更新存储的密码,3)用新密码重新验证。 - bimsapi
自定义身份验证提供程序是最重要的。但是如果你已经因为其他原因而已经有它... - Adrian Ber


你可以尝试子类化 SimpleUrlAuthenticationSuccessHandler 并实现用于检查密码到期的自定义逻辑。对此的引用 SimpleUrlAuthenticationSuccessHandler 可以传递给应用程序上下文中的form-login元素。


1
2018-01-12 12:15