Programming/Spring

Spring Security: Authentication

사랑우주인 2022. 1. 21. 15:09

Authentication

 

- 세션 영역 안에는 시큐리티 세션 영역이 존재핸다. 

- 시큐리티 세션에 들어 갈 수 있는 객체 타입은 Authentication이다. 

- 시큐리티 세션에 Authentication 객체가 들어갔다? = 로그인이 됐다! 

- Authentication 객체 안에는 2가지 타입만 들어갈 수 있다(UserDetails, OAuth2User)

- Authentication가 필요할 때마다 컨트롤에서 DI 할 수 있다. 

AuthenticationPrincipal이 될 수 있는 2가지 타입

 

1. UserDetails: 일반 로그인

2. OAuth2User: OAuth 로그인

 

단점: 컨트롤에서 AuthenticationPrincipal 꺼낼 때 타입을 구분해줘야 한다. 

해결: UserDetails와 OAuth2User을 둘 다 구현한 구현체를 만든다.(본인은 UserAccount 클래스를 만들었다.)

 

UserAccount.class

@Getter
@Slf4j
public class UserAccount implements UserDetails, OAuth2User {
    private static final long serialVersionUID = 1L;

    private Account account;
    private Map<String, Object> attributes;

    // 일반 시큐리티 로그인시 사용
    public UserAccount(Account account){
        this.account=account;
    }

    // OAuth2.0 로그인시 사용
    public UserAccount(Account account, Map<String, Object> attributes) {
        this.account = account;
        this.attributes = attributes;
    }


    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {

        List<String> roles=account.getRoleList();
        return roles.stream()
                .map(r->new SimpleGrantedAuthority("ROLE_"+ r))
                .collect(Collectors.toSet());

    }

    @Override
    public String getPassword() {
        return account.getPassword();
    }

    @Override
    public String getUsername() {
        if(account.getEmail()==null)
            return account.getNickname();

        return account.getEmail();
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }



    @Override
    public Map<String, Object> getAttributes() {
        return attributes;
    }

    @Override
    public String getName() {
        return account.getId()+"";
    }

}

 

OAuth2Controller.class

@Slf4j
@RestController
@RequiredArgsConstructor
public class OAuth2Controller {


    @PreAuthorize("isAuthenticated()")
    @GetMapping("/oauth2/user")
    public UserAccount getOAuth2User(@AuthenticationPrincipal UserAccount user) {

        return user;
    }

    @PreAuthorize("isAuthenticated()")
    @GetMapping("/site/user")
    public UserAccount getSiteUser(@AuthenticationPrincipal  UserAccount user) {

        return user;
    }

    @PreAuthorize("isAuthenticated()")
    @GetMapping("/user")
    public UserAccount getUser(@AuthenticationPrincipal  UserAccount user) {

        return user;
    }


}