Spring Security is a framework that provides authentication, authorization, and protection against common attacks.
Spring Docs에서 말하는 Spring Security의 정의이다. 두 개의 단어에 집중해보자.
즉, 시큐리티는 인증된 사용자인지 확인하고 허용된 자원만 접근하도록 제한하는 역할을 한다.
그렇다면 시큐리티는 인증을 어떻게 구현했을까?
시큐리티를 사용하다 보면 아래와 같은 객체들을 자주 마주치게 된다.
getName()
유저 이름 정도만 요구하듯 굉장히 간단하다.public interface Principal {
public boolean equals(Object another);
public String toString();
public int hashCode();
public String getName();
public default boolean implies(Subject subject) {
if (subject == null)
return false;
return subject.getPrincipals().contains(this);
}
public interface Authentication extends Principal, Serializable {
Collection<? extends GrantedAuthority> getAuthorities();
Object getCredentials();
Object getDetails();
Object getPrincipal();
boolean isAuthenticated();
void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException;
}
Principal: 유저 정보를 담은 객체이다. Object 타입이라 위에서 본 Principal 인터페이스가 구현된 객체라면 얼마든지 커스텀이 가능하다.
Credentials: Principal이 올바르다고 입증하는 객체이다. 일반적으로 비밀번호를 저장한다.
Authorities: 인증된 유저가 소유한 권한 목록을 저장한다.
Details: 인증 요청에 대한 부가 정보를 저장한다.
Authenticated: boolean 타입으로 인증 여부 구분한다.
Principal이 Authentication 안에 선언되어 사용되는 것처럼 보여진다. 둘을 다르게 생각하기 보다 유저 정보
와 인증 정보
가 저장된 객체라고 생각하자.
public interface SecurityContext extends Serializable {
Authentication getAuthentication();
void setAuthentication(Authentication authentication);
}
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
그렇다면 유저 정보
를 가져오기 위해 자주 사용하는 어노테이션인 @AuthenticationPrincipal
의 동작을 예상해볼 수 있을 것이다.
SecurityContextHolder에 담겨있는 Authentication 객체를 꺼내 getPrincipal()를 실행한 결과를 매핑한다.
지금까지 시큐리티가 유저 정보
와 인증 정보
를 어떻게 저장하는 지 알아보았다.
다음 포스트에선 어떻게 인증, 인가를 처리하는 지 알아보고자 한다.