Custom User 만들기
DB에서 보안적인 검사없이 바로 데이터를 가져올 때는 VO를 그대로 활용할 수 있었으나
스프링 시큐리티에서는 인가된 자료만 취급할 수 있습니다.
DB의 데이터를 원하는 value object로 만들기 위해서는
Spring security가 가지고 있는 User의 자식클래스를 활용해 커스텀을 생성해야 합니다.
spring security의 default 인 User 는
username과 password,
GrantedAuthority를 따온 authorities collection 자료형을
필요로 하고 있는 것을 확인할 수 있습니다.
User를 상속한 클래스를 만들고
멤버변수로 VO를 선언해준 다음
생성자에서 username, password, auth 최소 3항목을 입력해줘야 한다는 것을 알 수 있습니다.
제가 필요한 자료형과 일치시키기 위해
커스텀을 아래에 생성해보도록 하겠습니다.
domain에 CustomUser 클래스를 생성하고
user를 extends 하고 import했습니다.
그 후 private MemberVO를 생성하고 @Getter 어노테이션을 달아줍니다.
package com.ict.domain;
import java.util.Collection;
import java.util.stream.Collectors;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import lombok.Getter;
@Getter
public class CustomUser extends User {
private MemberVO member;
public CustomUser(String username, String password, Collection<? extends GrantedAuthority> auth) {
super(username, password, auth);
}
public CustomUser(MemberVO vo) {
super(vo.getUserId(),
vo.getUserPw(),
vo.getAuthList().stream().map(author ->
new SimpleGrantedAuthority(author.getAuth()))
.collect(Collectors.toList()));
this.member = vo;
}
}
저의 MemberVO에 맞는 자료형으로 user를 생성했다면
이제 DB와 연동이 잘 되는 지 확인해보아야 합니다.
package com.ict.security;
import org.springframework.beans.factory.annotation.Autowired;
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 com.ict.domain.CustomUser;
import com.ict.domain.MemberVO;
import com.ict.mapper.MemberMapper;
import lombok.extern.log4j.Log4j;
@Log4j
@Service
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private MemberMapper mapper;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
log.warn("유저 이름 확인 : " + username);
MemberVO vo = mapper.read(username);
log.warn("확인된 username으로부터의 정보 디버깅 : " + vo);
return vo == null? null : new CustomUser(vo);
}
}
security-context와 연결되어 있는
CustomUserDetailsService 가 memeber vo를 요청하고 return하도록
위와 같이 수정해주었습니다.
톰캣을 키고 확인해보면
이제 DB의 데이터와 연동되어 로그인에 성공했습니다.