스프링 시큐리티 UserDetailsService 구현 질문입니다.

1,506 views
Skip to first unread message

쿠이

unread,
Nov 1, 2013, 1:24:46 AM11/1/13
to ks...@googlegroups.com
현제 UserDetailsService 를 implements 해서 구현을 하려고 하는데요

public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {

logger.info("====> 인증 시작(" + userName +") <====");

/* DB를 이용할 경우 이 부분을 DB에서 가져오는걸로 변경하면 된다. */
PreludebUser preludebUser = new PreludebUser(); 
try {
/* DB를 이용할 경우 이 부분을 DB에서 가져오는걸로 변경하면 된다. 이 값은 단순히 테스트하기위한 Mock value */
preludebUser.setUserName("test"); /* TODO test 아이디가 아니어도 비밀번호만 맞으면 통과됨. 심각한 오류. */
preludebUser.setSaltKey("1111"); /* saltKey 값은 DB에서 가지고 있어야 하며 DB Password 필드에는 암호화 + salt 가 적용된 비밀번호가 저장되어있어야 한다. */
preludebUser.setUserPassword(encoder.encodePassword("test1", saltSource.getSalt(preludebUser))); /* DB에 미리 암호화 + salt 방식이 적용되서 저장되어 있어야 한다. */
preludebUser.addAuthorities(setUserAuthGrade(9));
if ( (preludebUser.getUsername() == null) || (preludebUser.getUsername().equalsIgnoreCase("")) ) {
logger.info(">>>> 유저 정보가 존재하지 않습니다.");
throw new CooiException(new UsernameNotFoundException(">>>> 유저 정보가 존재하지 않습니다."));
}
logger.info(">>>> userName = " + userName);
logger.info(">>>> preludebUser userName = " + preludebUser.getUsername());
logger.info(">>>> salt userPassword = " + encoder.encodePassword("test1", saltSource.getSalt(preludebUser)));
logger.info(">>>> userPassword = " + encoder.encodePassword("test1", null));
} catch ( CooiException e ) {

logger.error(e.getMessage(), e);
throw new CooiException(e.getMessage(), e);
} catch ( Exception e ) {
logger.error(">>>> 인증 하는 과정 중 오류가 발생하였습니다.", e);
throw new CooiException(">>>> " + e.getMessage(), e);
} finally {
logger.info("====> 인증 완료(" + userName +") <====");
}
return preludebUser;
}

이렇게 구현은 해놨습니다.

근데 여기서  일단 DB가 없는 관계로 하드코딩으로 사용자 패스워드랑 유저 이름을

preludebUser.setUserName("test");
preludebUser.setUserPassword(encoder.encodePassword("test1", saltSource.getSalt(preludebUser)));

이렇게 셋팅하였습니다.

그리고 나서 클라이언트에서 j_username 에 test1111, j_password 에 test1 넣었습니다.

정상적이라면 아이디와 패스워드가 안맞아서 오류를 호출해야 정상인데 패스워드만 맞으면 정상 로그인으로 간주를 하네요..

어느부분이 잘못됐는지 궁금합니다.

Ki-Seok Kim

unread,
Nov 1, 2013, 2:08:02 AM11/1/13
to ks...@googlegroups.com
userName 이 파라미터로 넘어오는 이유는요 userName 을 key 해서 DB를 조회 해야하기때문이에요..

여기서 DB를 조회해서 얻는 정보는요 password 랑 4가지 접근 권한 정도가 있는데요

여기서 

preludebUser.setUserPassword(encoder.encodePassword("test1", saltSource.getSalt(preludebUser)));

이걸로 password "test1" 을 설정해버리면 userName 이랑 상관없이 test1111의 사용자의 비밀번호는 test1 이니까 j_password  에 들어온 값과 비교하라고 명령을 내리는 결과입니다.

즉 의도치 않게 test1111 의 비밀번호는 test1 이 되어버립니다.


preludebUser.setUserPassword(getPassword("test1111"));

이런식으로 해서 test1111의 비밀번호를 DB에서 조회한후 설정해야합니다.



2013/11/1 쿠이 <phka...@gmail.com>

--
Google 그룹스 'Korea Spring User Group' 그룹에 가입했으므로 본 메일이 전송되었습니다.
이 그룹에서 탈퇴하고 더 이상 이메일을 받지 않으려면 ksug+uns...@googlegroups.com에 이메일을 보내세요.
http://groups.google.com/group/ksug에서 그룹을 방문하세요.
더 많은 옵션을 보려면 https://groups.google.com/groups/opt_out을(를) 방문하세요.

이수홍

unread,
Nov 1, 2013, 2:34:08 AM11/1/13
to ks...@googlegroups.com
일단 UserDetailService는 해당 username( 보통 id )를 파라메터로 사용자 정보를 가져오는 서비스입니다.

그래서 j_username 파라메터로 username을 넘겨주면 그 정보를 바탕으로 

DB를 검색하거나 LDAP으로 검색하거나 OpenID를 검색하거나 이런식으로 사용자 인증 정보를 조회하여 

사용자 패스워드 등 기타 정보를 조회 하게됩니다. 

참고로 

패스워드 비교는 여기서 하는게 아닙니다. 인증정보만 가져오는 부분입니다. 

패스워드 비교는 “AuthenticationProvider” 보통 여기에서 하게됩니다. 가장 많이사용되는 구현체는 “DaoAuthenticationProvider" 입니다.

다시 UserDetailService를 이야기 하겠습니다.


지금 예제 소스에서는 해당 username을 파라메터로 넘겼으나 별 용도가 없이 사용 되네요 

테스트 하시려면 

PreludebUser preludebUser = new PreludebUser(); 

if ( preludebUser.getUserName().equals(username) ) {
return preludebUser;
}
else return null;

이런 형태로 테스트 하셔야 될듯하네요 



2013. 11. 1., 오후 2:24, 쿠이 <phka...@gmail.com> 작성:

UserDetailsService

Reply all
Reply to author
Forward
0 new messages