Published on

[ Spring Sequrity ] 스프링 시큐리티 아키텍처

Authors
  • avatar
    Name
    유사공대생
    Twitter

스프링 시큐리티 공식문서

위 링크에서의 문서를 직접 보면서 이해한대로 정리하려고 한다.

이 문서는 스프링 시큐리티를 처음 시작하는 사람들을 위한 가이드입니다. 영문인걸 감안해서 중요한 단어는 영어 그대로 표현하겠습니다.

Authentication and Access Control

Authentication은 who are you? 이고 Authorization은 whar are you allowed to do? 입니다. 여기서 몇몇은 authorization이 헷갈려서 authorization 대신에 access cotrol이라고 부르기도 합니다.

Spring Security는 인증(authentication)과 권한 부여(authorization-access contorl)를 분리하도록 설계된 아키텍처를 가지고 있으며, 둘 다에 대한 전략과 확장 지점을 가지고 있습니다.

Authentication

authentication의 가장 주요한 interface 전략은 AuthenticationManager입니다.

public interface AuthenticationManager {

  Authentication authenticate(Authentication authentication)
    throws AuthenticationException;
}

AuthenticationManagerauthenticate() 함수는 3가지 기능이 있습니다.

  • Authentication반환.(보통 authenticated = true) Authentication은 유효한 Principal인지 검증합니다.
  • AuthenticationException 반환. 만약 유요하지 않은 principal일 때 반환됩니다.
  • 만약 결정할 수 없을 때 null 반환

가장 일반적으로 사용되는 AuthenticationManager의 구현은 ProviderManager입니다. 이는 AuthenticationProvider 인스턴스의 체인에 위임합니다. AuthenticationProvider는 AuthenticationManager와 비슷하지만, 호출자가 주어진 Authentication 유형을 지원하는지 여부를 질의할 수 있도록 추가 메서드가 있습니다.

public interface AuthenticationProvider {

	Authentication authenticate(Authentication authentication)
			throws AuthenticationException;

	boolean supports(Class<?> authentication);
}

supports() 메서드의 Class<?> 인자는 실제로는 Class<? extends Authentication>입니다(authenticate() 메서드로 전달되는 것을 지원하는지만 물어봅니다). ProviderManagerAuthenticationProviders의 체인에 위임함으로써 동일한 애플리케이션 내에서 여러 다른 인증 메커니즘을 지원할 수 있습니다. ProviderManager가 특정 Authentication 인스턴스 유형을 인식하지 못하면, 그것은 건너뛰어집니다.

ProviderManager는 선택적인 부모(parent)를 가질 수 있으며, 모든 제공자가 null을 반환할 경우 이 부모에게 상담할 수 있습니다. 부모가 사용할 수 없는 경우 null Authentication은 AuthenticationException을 초래합니다.

때로는 애플리케이션이 보호된 리소스의 논리적 그룹을 가질 수 있습니다(예를 들면, /api/\*\*와 같은 경로 패턴에 일치하는 모든 웹 리소스) 그리고 각 그룹은 자체 전용 AuthenticationManager를 가질 수 있습니다. 종종, 그 중 각각이 ProviderManager이며, 부모를 공유합니다. 그러면 부모는 모든 제공자에 대한 폴백(fallback) 역할을 하는 종류의 "글로벌" 리소스가 됩니다.

image

Figure 1. ProviderManager를 활용한 AuthenticationManager의 계층구조

Authentication Managers 커스터마이징하기

스프링 시큐리티는 우리가 만드는 어플리케이션에 공통적인 authentication manager 기능을 빠르게 구축할 수 있도록 설정 도우미(configuration helpers)를 제공합니다. 가장 흔히 사용되는 도우미는 바로 AuthenticationManagerBuilder입니다. AuthenticationManagerBuilder는 메모리, JDBC, 혹은 LDAP 유저의 세부정보를 설정하거나, 커스텀 UserDetailsService를 추가할 수 있습니다.

다음 예시는 우리가 전역 AuthenticationManager를 설정하는 예시입니다.

@Configuration
public class ApplicationSecurity extends WebSecurityConfigurerAdapter {

   ... // web stuff here

  @Autowired
  public void initialize(AuthenticationManagerBuilder builder, DataSource dataSource) {
    builder.jdbcAuthentication().dataSource(dataSource).withUser("dave")
      .password("secret").roles("USER");
  }
}

이 예시는 웹 어플리케이션에 연결됩니다. 하지만 AuthenticationManagerBuilder는 좀 더 넓게 적용가능합니다.(아래 Web Security에서 어떻게 웹 어플리케이션 보안이 구현되는지 자세한 정보를 알 수 있습니다.)

AuthenticationManagerBuilderBean@AutoWired됩니다.- 이게 전역 AuthenticatoinManager를 만드는 걸 가능하게 합니다.

반대로, 다음 예시를 봅시다.

@Configuration
public class ApplicationSecurity extends WebSecurityConfigurerAdapter {

   ... // web stuff here

  @Autowired
  public void initialize(AuthenticationManagerBuilder builder, DataSource dataSource) {
    builder.jdbcAuthentication().dataSource(dataSource).withUser("dave")
      .password("secret").roles("USER");
  }

}

만약 우리가 @Override 메서드를 configurer에 넣게 된다면, AuthenticationManagerBuilder는 오로지 "로컬" AuthenticationManager를 빌드하는데 사용됩니다.(이게 전역인 놈의 자식입니다.)

Spring Boot 애플리케이션에서는 다른 빈(bean)으로 전역 AuthenticationManager를 @Autowired 할 수 있지만, 명시적으로 직접 노출하지 않는 한 로컬 AuthenticationManager로는 그렇게 할 수 없습니다.

Spring Boot는 우리가 우리만의 빈 타입의 AuthenticationManager를 제공하는 게 아니라면 기본 전역 AuthenticationManager(오직 한 유저에게) 제공합니다. 기본적으로는 커스텀된 전역 AuthenticatoinManager를 부분적으로 필요한 게 아니라면, 유저 한명으로 안전해서 걱정할 필요가 없습니다.