当前位置: 首页 > 知识库问答 >
问题:

使用Spring Security更改密码

谢泉
2023-03-14

我使用,

  • Spring Framework 4.0.0 RELEASE(GA)
  • Spring Security 3.2.0 RELEASE(GA)
  • Struts 2.3.16

我在其中使用,

org.springframework.security.authentication.dao.DaoAuthenticationProvider

我的spring-security.xml文件如下所示。

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
             xmlns:beans="http://www.springframework.org/schema/beans"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
           http://www.springframework.org/schema/security
           http://www.springframework.org/schema/security/spring-security-3.2.xsd">

    <http pattern="/Login.jsp*" security="none"></http>

    <http auto-config='true' use-expressions="true" disable-url-rewriting="true" authentication-manager-ref="authenticationManager">
        <session-management session-fixation-protection="newSession">
            <concurrency-control max-sessions="1" error-if-maximum-exceeded="true" />
        </session-management>

        <csrf/>

        <headers>
            <xss-protection />
            <frame-options />
            <!--<cache-control />-->
            <!--<hsts />-->
            <content-type-options /> <!--content sniffing-->
        </headers>

        <intercept-url pattern="/admin_side/**" access="hasRole('ROLE_ADMIN')" requires-channel="any"/>

        <form-login login-page="/admin_login/Login.action" authentication-success-handler-ref="loginSuccessHandler" authentication-failure-handler-ref="authenticationFailureHandler"/>
        <logout logout-success-url="/admin_login/Login.action" invalidate-session="true" delete-cookies="JSESSIONID"/>
    </http>

    <beans:bean id="encoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>

    <beans:bean id="daoAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
        <beans:property name="userDetailsService" ref="userDetailsService"/>
        <beans:property name="passwordEncoder" ref="encoder" />
    </beans:bean>

    <beans:bean id="authenticationManager" class="org.springframework.security.authentication.ProviderManager">
        <beans:property name="providers">
            <beans:list>
                <beans:ref bean="daoAuthenticationProvider" />
            </beans:list>
        </beans:property>
    </beans:bean>

    <authentication-manager>
        <authentication-provider user-service-ref="userDetailsService"/>            
    </authentication-manager>

    <beans:bean id="loginSuccessHandler" class="loginsuccesshandler.LoginSuccessHandler"/>
    <beans:bean id="authenticationFailureHandler" class="loginsuccesshandler.AuthenticationFailureHandler" />

    <global-method-security secured-annotations="enabled" proxy-target-class="false" authentication-manager-ref="authenticationManager">
        <protect-pointcut expression="execution(* admin.dao.*.*(..))" access="ROLE_ADMIN"/>
    </global-method-security>
</beans:beans>

UserDetailsService的实现如下。

@Service(value="userDetailsService")
public final class UserDetailsImpl implements UserDetailsService {

    @Autowired
    private final transient UserService userService = null;
    @Autowired
    private final transient AssemblerService assemblerService = null;

    @Override
    @Transactional(readOnly = true, propagation = Propagation.REQUIRED)
    public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
        UserTable userTable = userService.findUserByName(userName);

        if (userTable == null) {
            throw new UsernameNotFoundException("User name not found.");
        } else if (!userTable.getEnabled()) {
            throw new DisabledException("The user is disabled.");
        } else if (!userTable.getVarified()) {
            throw new LockedException("The user is locked.");
        }

        //Password expiration and other things may also be implemented as and when required.
        return assemblerService.buildUserFromUserEntity(userTable);
    }
}

@Service(value="assembler")
@Transactional(readOnly = true, propagation=Propagation.REQUIRED)
public final class AssemblerDAO implements AssemblerService {

    @Override
    public User buildUserFromUserEntity(UserTable userTable) {
        String username = userTable.getEmailId();
        String password = userTable.getPassword();
        boolean active = userTable.getEnabled();
        boolean enabled = active;
        boolean accountNonExpired = active;
        boolean credentialsNonExpired = active;
        boolean accountNonLocked = userTable.getVarified();
        Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();

        for (UserRoles role : userTable.getUserRolesSet()) {
            authorities.add(new SimpleGrantedAuthority(role.getAuthority()));
        }

        return new User(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);
    }
}

无需参考这些类。

我的问题是在使用时,

org.springframework.security.provisioning.JdbcUserDetailsManager

可以将UserDetailsManager注入控制器及其

public void changePassword(String oldPassword, String newPassword) throws AuthenticationException {
    //...
}

方法可用于更改密码。我从未尝试过这一点,但它可能大致实现如下。

<bean id="jdbcUserService" class="org.springframework.security.provisioning.JdbcUserDetailsManager">
    <property name="dataSource" ref="datasource" />
    <property name="authenticationManager" ref="authenticationManager" />
</bean>

在控制器中,应按如下方式注入。

@Autowired
@Qualifier("jdbcUserService")
public UserDetailsManager userDetailsManager;

我正在使用的方法中是否有Spring security提供的任何工具,或者在DAO中仅使用我自己的一个简单方法来更改当前登录用户的密码就足够了?如果我在任何地方做错了什么,请提出建议!

这个内容可能太大,无法回答这个问题,但我问这个问题是因为它是相当实验性的。

共有2个答案

柳胜
2023-03-14

我同意贾德斯捷夫的回答;

请注意,通过调用Spring的JdbcUserDetailsManager。changePassword(),Spring更新上下文保持器,并使用新密码更新数据库。

Spring不会处理cookie,因为它不会强制您的应用程序成为web应用程序。所以我想如果是这样的话,应用程序中的更高级别层应该会更新会话。

PS-出于好奇-您是如何实现注册流、忘记密码流等的?Spring也无法处理此问题。我写了一个项目来处理这些流。。。

桑鸿志
2023-03-14

更改密码的方法是一个很好的解决方案,因为在Spring Security中没有特殊功能

spring security中不存在这种特殊功能的原因是,如果使用会话,则不需要它。

由JSESSIONID cookie标识的用户当前会话仍然驻留在用户的浏览器中,并且在密码更改后仍然是有效会话。

当用户上次登录时检查旧密码时,会生成一个cookie并保存在内存中有效cookie的映射中。

临时身份验证令牌(cookie)仍然有效,并且具有最长生存期,更改数据库上的密码不会影响当前会话的有效性。

 类似资料:
  • 我无法使用keytool(java 8)更改PKCS密钥库密码。当我试图更改密钥密码时: 这意味着无法更改PKCS12密钥库的密钥密码。然后我尝试更改keystore密码: 这意味着,我们必须一起更改密钥库密码和密钥密码。但是没有命令可以改变两者。我能做什么呢?

  • 问题内容: 我目前有一个密钥库,其中只有我应该知道的特定密码。现在,我需要将对该密钥库的访问权授予其他人,因此我想: 1)更改密码,以便我可以与他人共享该密码并让他们签名 2)创建一个不同的密码并允许他们使用它进行签名。 这可能吗?以及-如果是-怎么样? 问题答案: 密钥库只有一个密码。您可以使用keytool进行更改: 要更改密钥的密码:

  • 我正在尝试使用命令行更新数据库用户的密码,但它对我不起作用。这是我正在使用的代码: 有人能告诉我这个代码有什么问题吗?

  • 本文向大家介绍更改Mysql root用户密码,包括了更改Mysql root用户密码的使用技巧和注意事项,需要的朋友参考一下 新下载了mysql,口令为空,如何修改root口令: 首先登陆mysql 注意需要 flush privileges; 更改Mysql root用户口令的内容小编就给大家介绍到这里,希望对大家有所帮助!

  • 问题内容: 我一直试图重置我的MySQL根密码。我已经运行了mysqld_safe –skip-grant- tables,更新了根密码,并检查了用户表以确保它在那里。重新启动mysql守护程序后,我尝试使用刚刚设置的新root密码登录,但仍然由于用户“ root”错误而拒绝访问。我也尝试过完全删除并重新安装mysql(包括删除my.cnf文件),但还是没有运气。有人对我下一步的工作有什么建议吗?