1. 배경 및 목적

   패스워드 분실 시 복구절차에 따라 임시 패스워드를 발급하고 임시 패스워드로 로그인하여 패스워드를 변경하도록 합니다.

2. 개발자 가이드   

   • 환경설정
     스프링 시큐리티와 계정관리를 연동하기 위한 AccountInitializer 클래스를 security-context.xml 에 빈으로 등록합니다.

security-context.xml
<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"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
    http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd" default-lazy-init="true">
      
    <!-- 계정관리 기능을 사용하기 위하여 AccountInitializer 클래스를 빈으로 등록하고 lazy-init 속성을 false 로 지정한다 -->
    <beans:bean class="smartsuit.app.bp.common.account.AccountInitializer" lazy-init="false"></beans:bean>
  
</beans:beans>

   스프링 시큐리티에서 로그인 처리에 필요한 UserDetailsService 인터페이스를 구현한 DefaultUserDetailsService 클래스에서 AccountService 를 이용하여 로그인된 사용자의 패스워드 초기화 상태를 판단하여 User 객체에 초기화여부를 boolean 유형으로 관리합니다.

DefaultUserDetailsService.java
package smartsuit.infra;
import java.util.Date;
import java.util.Map;
import javax.inject.Inject;
import javax.transaction.Transactional;
import org.apache.ibatis.session.SqlSession;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import lombok.AccessLevel;
import lombok.Setter;
import lombok.experimental.FieldDefaults;
import smartsuit.app.bp.common.account.AccountService;
@Transactional
@Service("defaultUserDetailsService")
@FieldDefaults(level=AccessLevel.PROTECTED)
public class DefaultUserDetailsService implements UserDetailsService {
    @Inject
    SqlSession sqlSession;
     
    @Inject
    AccountService accountService; 
     
    @Setter
    String accountCredentialsNonExpiredName = "pw_mod_dt";
     
    @Override
    public UserDetails loadUserByUsername(String username)
            throws UsernameNotFoundException {
         
        User user = sqlSession.selectOne("infra-UserDetails.getUserDetails", username);
        if (user == null) {
            throw new UsernameNotFoundException(username + " id does not exist.");
        }
        //사용자 정보 조회
        Map<String,Object> userInfo = sqlSession.selectOne("infra-UserDetails.getSessionUserInfo", username);
        user.setUserInfo(userInfo);
        ...(생략)
        //비밀번호 초기화 여부(스프링 시큐리티의 UserDetails 인터페이스는 패스워드 초기화 여부에 대한 필드가 존재하지 않기 때문에 별도의 필드를 추가해야 하며(솔루션의 User 클래스에 credentialsNonInitialized 필드가 구현되어 있습니다.)
		user.setCredentialsNonInitialized("N".equals(userInfo.get(accountCredentialsNonInitializedName)));
        ...(생략)
         
        return new UserDetailsProxy(user);
    }  
}

   계정관리에서 설정된 패스워드 복잡도 설정을 클라이언트에서 사용하기 위하여 SharedController 클래스의 getSessionUser 메소드를 통하여 계정관리 설정을 내려줍니다.

SharedController.java
@Controller
public class SharedController {
  
    @Inject
    AccountService accountService;
  
    @RequestMapping (value = "/**/getSessionUser.do")
    public @ResponseBody Map<String,Object> getSessionUser() {
        User user = Auth.getCurrentUser();
        Map<String,Object> sessionUser = Maps.newHashMap();
        sessionUser.put("credentialsNonExpired", user.isCredentialsNonExpired());
		//패스워드 초기화 상태 전달
        sessionUser.put("credentialsNonInitialized", user.isCredentialsNonInitialized());
        sessionUser.put("userInfo", user.getUserInfo());
        //계정관리 설정값을 포함하여 클라이언트에 전달 합니다.
        sessionUser.put("accountSettings", accountService.getAccountSettings());
        sessionUser.put("authorities", user.getAuthorities());
        return sessionUser;
    }
}

   클라이언트의 SCSessionManager 의 isCredentialsNonInitialized 함수를 이용하여 sc-mdi.html 페이지에서 패스워드 초기화 사앹를 판단하고 패스워드 변경 팝업을 활성화 합니다.

sc-mdi.html
/******************************
* 비밀번호 변경 주기 체크
******************************/
userPopupCheck: function() {
    var me = this;
    //패스워드 초기화
	if(!SCSessionManager.isCredentialsNonInitialized()) {
		UT.alert(me.translate("STD.MDI1005"), function() { //"임시 비밀번호로 로그인 되었습니다. 비밀번호를 변경해주시길 바랍니다."
			me.popupChangePassword();
		}, true);	
    }
},
 
popupChangePassword: function() {
    var me = this;
    me.importLink("./ui/lib/mdi/sc-mdi-pw-popup.html", function() {
        if(!me.pwChangePopup) {
            me.pwChangePopup = UT.popup("sc-mdi-pw-popup", me, 350, 267, {
                "logout": function() {
                    //패스워드 변경 후 로그아웃시켜 재로그인 하도록 합니다.
                    me.logout();
                }
            }, {title: me.translate("비밀번호변경"), closable:true});
        }
        me.pwChangePopup.show();
    });
}

 



 

 

  • No labels