使用 Spring security 更改密码 [英] Changing password using Spring security

查看:89
本文介绍了使用 Spring security 更改密码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用,

  • Spring Framework 4.0.0 发布(正式版)
  • Spring Security 3.2.0 发布(正式版)
  • Struts 2.3.16

我在其中使用,

org.springframework.security.authentication.dao.DaoAuthenticationProvider

用于身份验证.我的 spring-security.xml 文件如下所示.

for authentication. My spring-security.xml file looks like the following.

<?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>

UserDetailsS​​ervice 的实现如下.

@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);
    }
}

下面只是一个帮助服务,它转换了一个 Spring User 对象要使用的用户实体.

And the following is just a helper service that converts a user entity which is to be used by a Spring User object.

@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);
    }
}

无需引用这些类.

我的问题是,在使用时,

My question is that while using,

org.springframework.security.provisioning.JdbcUserDetailsManager

UserDetailsManager 可以注入控制器及其

UserDetailsManager can be injected into a controller and its

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

方法可用于更改密码.我从未尝试过,但大致可以如下实现.

method can be used to change the password. I never tried this but it may roughly be implemented like the following.

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

在控制器中,它应该被注入如下.

and in a controller, it should be injected as follows.

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

<小时>

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


Is there any facility provided by Spring security in the approach I'm using or just a simple method of my own in a DAO to change the password of the current logged-in user is sufficient? Kindly suggest, if I'm doing something wrong anywhere!

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

推荐答案

我同意@jhadesdev 的回答;

I agree with the answer @jhadesdev;

请注意,通过调用 Spring 的 JdbcUserDetailsManager.changePassword(),Spring 会更新上下文持有者,并使用新密码更新数据库.

Note that by calling Spring's JdbcUserDetailsManager.changePassword(), Spring updates the context-holder, plus updates the DB with the new password.

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

Spring does not handle the cookie, since it does not force your app to be a web application. so I guess if that is the case, a higher level layer in your app should update the session.

PS - 出于好奇 - 您是如何实现注册流程、忘记密码流程等的?Spring 也不处理这个.我编写了一个项目来处理这些流程...

PS - out of curiosity - how did you implement the registration flow, and forgot password flow, etc? Spring does not handle this either. I have written a project that takes care of these flows...

这篇关于使用 Spring security 更改密码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆