복붙노트

[SPRING] 스프링 보안을 사용하여 비밀번호 변경하기

SPRING

스프링 보안을 사용하여 비밀번호 변경하기

나는 사용한다,

내가 사용하는

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

그리고 다음은 Spring User 객체가 사용할 사용자 엔티티를 변환하는 헬퍼 서비스 일 뿐이다.

@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 보안에 의해 제공되는 기능이 있습니까, 아니면 현재 로그인 한 사용자의 암호를 변경하기 위해 DAO에서 내 자신 만의 간단한 방법으로 충분합니까? 내가 어디서든 뭔가 잘못하고 있다면 친절하게 제안하십시오!

이 내용은 너무 커서이 질문에 답할 수는 없지만 꽤 실험적인 무언가이기 때문에이 질문을하고 있습니다.

해결법

  1. ==============================

    1.나는 @jhadesdev라는 대답에 동의한다.

    나는 @jhadesdev라는 대답에 동의한다.

    Spring의 JdbcUserDetailsManager.changePassword ()를 호출함으로써 Spring은 context-holder를 업데이트하고 DB에 새로운 암호를 업데이트한다.

    Spring은 앱을 웹 애플리케이션으로 강제하지 않기 때문에 쿠키를 처리하지 않습니다. 그래서 나는 그 경우에, 귀하의 애플 리케이션에서 상위 레이어는 세션을 업데이 트해야합니다 같아요.

    PS - 호기심에서 - 어떻게 등록 흐름을 구현하고 암호 흐름 등을 잊었습니까? Spring도이 문제를 처리하지 않는다. 나는 이러한 흐름을 처리하는 프로젝트를 작성했습니다 ...

  2. ==============================

    2.스프링 보안에서 특별한 기능이 없기 때문에 암호를 변경하는 방법은 좋은 해결책입니다.

    스프링 보안에서 특별한 기능이 없기 때문에 암호를 변경하는 방법은 좋은 해결책입니다.

    스프링 보안에서 특별한 기능이없는 이유는 세션을 사용하는 경우에는 필요하지 않기 때문입니다.

    JSESSIONID 쿠키로 식별되는 사용자의 현재 세션은 여전히 ​​사용자 브라우저에 상주하며 비밀번호가 변경된 후에도 유효한 세션입니다.

    마지막으로 사용자가 로그인 할 때 이전 암호를 검사하면 쿠키가 생성되어 메모리의 유효한 쿠키 맵에 보관됩니다.

    임시 인증 토큰 (쿠키)은 여전히 ​​유효하며 최대 수명 및 데이터베이스의 암호 변경은 현재 세션 유효성에 영향을주지 않습니다.

  3. from https://stackoverflow.com/questions/20919913/changing-password-using-spring-security by cc-by-sa and MIT license