일반 Spring Security로 로그인 했을경우와 구글과 같은 OAuth2.0으로 로그인 했을 경우의 인증 타입 차이
Spring Security 로그인 시 UserDetails에서 권한을 관리하는데 이때 구글과 같은 OAuth2.0 으로 로그인 할 시 OAuth2User에서 해당 유저의 정보들을 획득 할 수 있다.
보통 UserDetails를 상속받아 권한을 관리하는데 이때 컨트롤러 단에서 Authentication 객체를 받으면 Principal을 받아 쓸 수 있다.
@GetMapping("/login/info")
public void loginTest(Authentication authentication,
@AuthenticationPrincipal UserDetails userDetails){
PrincipalDetails principalDetails = (PrincipalDetails) authentication.getPrincipal();
System.out.println("authentication: " + principalDetails.getUsername());
}
OAuth2.0 로그인 시에도 아래와 같이 Authentication 객체에서 rincipal을 받아 쓸 수 있는데 이때 일반 로그인 할 때와 형변환 되는 객체가 OAuth2User 로 다르다.
@GetMapping("/login/oauth/info")
public void loginTest(Authentication authentication,
@AuthenticationPrincipal UserDetails userDetails){
OAuth2User oAuth2User = (OAuth2User) authentication.getPrincipal();
System.out.println("Attributes: " + oAuth2User.getAttributes());
이 두 권한을 함께 관리하기 위해서 UserDetails와 OAuth2User를 둘다 상속받아 관리한다.
// Secutiry Session => Authentication => UserDetails(PrincipalDetails)
public class PrincipalDetails implements UserDetails, OAuth2User {
private User user;
private Map<String, Object> attributes;
// 일반 로그인
public PrincipalDetails(User user){
this.user = user;
}
// OAuth 로그인
public PrincipalDetails(User user, Map<String, Object> attributes){
this.user = user;
this.attributes = attributes;
}
// UserDetails //
@Override // 해당 User의 권한을 리턴하는곳.
public Collection<? extends GrantedAuthority> getAuthorities() {
Collection<GrantedAuthority> collect = new ArrayList<>();
collect.add(new GrantedAuthority() {
@Override
public String getAuthority() {
return user.getRole();
}
});
return collect;
}
@Override
public String getPassword() {
return user.getPassword();
}
@Override
public String getUsername() {
return user.getUsername();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
// ex) 1년동안 로그인 안하면 휴먼계정
return true;
}
// OAuth2User //
@Override
public Map<String, Object> getAttributes() {
return attributes;
}
@Override
public String getName() {
return null;
}
}
어떤 로그인을 하던 User Entity 정보를 이 클래스에 담아두면 PrincipalDetails 객체로 유저 권한을 관리할 수 있다.
@GetMapping("/user")
public @ResponseBody String user(@AuthenticationPrincipal PrincipalDetails principalDetails){
return principalDetails.getUsername();
}
공부 출처 : 인프런 스프링부트 시큐리티 & JWT 강의