[Spring] Spring Security란?

원알렉스·2020년 7월 20일
7

Spring

목록 보기
3/3
post-thumbnail
post-custom-banner

1) Spring Security란?

  • Spring Security는 Spring 기반의 애플리케이션의 보안(인증과 권한, 인가 등)을 담당하는 Spring 하위 프레임워크입니다.
  • Spring Security는 "인증" 과 "권한" 에 대한 부분을 Filter의 흐름에 따라 처리합니다.
  • Spring Security는 보안과 관련해서 체계적으로 많은 옵션을 제공해주기 때문에 개발자 입장에서는 일일이 보안 관련 로직을 작성하지 않아도 된다는 장점이 있습니다.

2) 인증과 인가란?

인증(Authentication)

  • 해당 사용자가 본인이 맞는지를 확인하는 절차

인가(Authorization)

  • 인증된 사용자가 요청한 자원에 접근 가능한지를 결정하는 절차
  • Spring Security는 기본적으로 인증 절차를 거친 후에 인가 절차를 진행하게 되며, 인가 과정에서 해당 리소스에 대한 접근 권한이 있는지 확인을 하게 됩니다.
  • 이러한 인증과 인가를 위해 Principal 을 아이디로, Credential 을 비밀번호로 사용하는 Credential 기반의 인증 방식 을 사용합니다.
  • Principal(접근 주체) : 보호 받는 리소스에 접근하는 대상
  • Credential(비밀번호) : 리소스에 접근하는 대상의 비밀번호

3) Spring Security의 주요 모듈

Authentication

  • Authentication 은 현재 접근하는 주체의 정보와 권한을 담는 인터페이스입니다.
  • SecurityContext에 저장되며, SecurityContextHolder 를 통해 SecurityContext에 접근하고, SecurityContext 를 통해 Authentication 에 접근할 수 있습니다.

SecurityContext

  • Authentication을 보관하는 역할을 하며, SecurityContext를 통해 Authentication 객체를 꺼내올 수 있습니다.

SecurityContextHolder

  • SecurityContextHolder는 보안 주체의 세부 정보를 포함하여 응용 프로그램의 현재 보안 컨텍스트에 대한 세부 정보가 저장됩니다.

Spring Security에서의 인증 처리 과정

  • usernamepassword를 조합해서 UsernamePasswordAuthenticationToken 인스턴스를 만듭니다.
  • 이 토큰은 검증을 위해 AuthenticationManager의 인스턴스로 전달됩니다.
  • AuthenticationManager는 인증에 성공하면 Authentication 인스턴스를 리턴합니다.
  • Authentication 인스턴스는 SecurityContextHolder에 저장됩니다.

UsernamePasswordAuthenticationToken

  • AuthenticationimplementsAbstractAuthenticationToken의 하위 클래스로 usernamePrincipal의 역할을 하고, passwordCredential의 역할을 합니다.
  • 첫번째 생성자는 인증 전의 객체를 생성하고, 두번째 생성자는 인증이 완료된 객체를 생성해줍니다.
public class UsernamePasswordAuthenticationToken extends AbstractAuthenticationToken {
    // 주로 사용자의 username에 해당함
    private final Object principal;
    // 주로 사용자의 password에 해당함
    private Object credentials;
    
    // 인증 완료 전의 객체 생성
    public UsernamePasswordAuthenticationToken(Object principal, Object credentials) {
		super(null);
		this.principal = principal;
		this.credentials = credentials;
		setAuthenticated(false);
	}
    
    // 인증 완료 후의 객체 생성
    public UsernamePasswordAuthenticationToken(Object principal, Object credentials,
			Collection<? extends GrantedAuthority> authorities) {
		super(authorities);
		this.principal = principal;
		this.credentials = credentials;
		super.setAuthenticated(true); // must use super, as we override
	}
}

AuthenticationProvider

  • 실제 인증에 대한 부분을 처리하는데, 인증 전의 Authentication 객체를 받아서 인증이 완료된 객체를 반환하는 역할을 합니다.

AuthenticationManager

  • 인증에 대한 부분은 AuthenticationManager를 통해서 처리하게 되는데, 실질적으로는 AuthenticationManager에 등록된 AuthenticationProvider에 의해 처리됩니다.

  • 인증이 성공하면 isAuthenticated=true 인 객체를 생성하여 SecurityContext에 저장합니다.

  • 실패할 경우에는 AuthenticationException을 발생시킵니다.

  • DaoAuthenticationProviderAbstractUserDetailsAuthenticationProvider를 상속받아 실제 인증 과정에 대한 로직을 처리합니다.

  • AuthenticationManagerDaoAuthenticationProvider를 등록하는 방법은 WebSecurityConfigurerAdapter를 상속해 만든 ApplicationSecurityConfig에서 할수 있습니다.

@Configuration
@EnableWebSecurity
public class ApplicationSecurityConfig extends WebSecurityConfigurerAdapter {

  private final PasswordEncoder passwordEncoder;

  @Autowired
  public ApplicationSecurityConfig(PasswordEncoder passwordEncoder,) {
    this.passwordEncoder = passwordEncoder;
  }

  @Override
  protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.authenticationProvider(daoAuthenticationProvider());
  }

  @Bean
  public DaoAuthenticationProvider daoAuthenticationProvider() {
    DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
    provider.setPasswordEncoder(passwordEncoder);
    provider.setUserDetailsService(applicationUserService);

    return provider;
  }
}

UserDetails

  • 인증에 성공하여 생성된 UserDetails 객체는 UsernamePasswordAuthenticationToken을 생성하기 위해 사용됩니다.
  • UserDetails 인터페이스의 경우 직접 개발한 ApplicationUserUserDetails를 implements하여 사용하면 됩니다

UserDetailsService

  • UserDetails 객체를 반환하는 단 하나의 메소드를 가지고 있는데, 일반적으로 이를 구현한 클래스의 내부에 UserRepository를 주입받아 DB에 연결하여 처리합니다.

GrantedAuthority

  • 현재 사용자(Principal)가 가지고 있는 권한들입니다.
  • 보통 ROLE_ADMIN, ROLE_USER와 같이 ROLE_의 형태로 사용됩니다.
profile
Alex's Develog 🤔
post-custom-banner

0개의 댓글