SecurityContext에 들어갈 수 있는 객체는 Authentication 타입뿐이다.
Authentication 안에도 저장할 수 있는 객체의 타입이 정해져있다.
그것은 UserDetails 타입과 OAuth2User 타입이다.
이 둘 중 하나여야, Authentication 객체 안에 저장할 수 있다.
회원가입 프로세스를 직접 구현한 경우 UserDetails 타입 객체를 저장하게 된다.
소셜로그인 구현시에는 OAuth2User 타입 객체를 저장하게 된다.
그런데 우리가 회원가입을 하게되면 우리는 User 오브젝트가 필요하다.
OAuth2User,UserDetails는 User 오브젝트가 포함하고있지 않는다.
따라서 위 두개의 타입을 세션에담아도 User 오브젝트가 없으므로 회원가입이 불가하다.
그래서 우리가 PrincipalDetails 클래스를 만들고 UserDetails를 implements해서 같은 타입으로 묶어서
PrincipalDetails클래스에 User 오브젝트를 넣어둔다.
해서 위 두타입을 묶는 PrincipalDetails 를 만든다.
public class PrincipalDetails implements UserDetails, OAuth2User {
private Member member;
private Map<String,Object> attributes;
//일반 로그인
public PrincipalDetails(Member member) {
this.member = member;
}
//OAuth 로그인
public PrincipalDetails(Member member, Map<String, Object> attributes) {
this.member = member;
this.attributes = attributes;
}
//권한을 리턴
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
Set<GrantedAuthority> roles = new HashSet<>();
for (String role : member.getAuth().split(",")) {
roles.add(new SimpleGrantedAuthority(role));
}
return roles;
}
// 사용자의 id를 반환
@Override
public String getUsername() {
return member.getEmail();
}
// 사용자의 password를 반환
@Override
public String getPassword() {
return member.getPassword();
}
// 계정 만료 여부 반환
@Override
public boolean isAccountNonExpired() {
// 만료되었는지 확인하는 로직
return true; // true -> 만료되지 않았음
}
// 계정 잠금 여부 반환
@Override
public boolean isAccountNonLocked() {
// 계정 잠금되었는지 확인하는 로직
return true; // true -> 잠금되지 않았음
}
// 패스워드의 만료 여부 반환
@Override
public boolean isCredentialsNonExpired() {
// 패스워드가 만료되었는지 확인하는 로직
return true; // true -> 만료되지 않았음
}
// 계정 사용 가능 여부 반환
@Override
public boolean isEnabled() {
// 계정이 사용 가능한지 확인하는 로직
return true; // true -> 사용 가능
}
//OAuth2
@Override
public Map<String, Object> getAttributes() {
return attributes;
}
우리는 PrincipalDetails클래스를 쓰면 OAuth2User타입으로 처리할수도있고 UserDetails타입으로 처리를 할 수 있게 된다.