Spring Security 정리

이창윤·2022년 7월 25일
0
post-thumbnail

Spring Security란?

스프링 기반의 어플리케이션의 보안을 담당하는 프레임워크

  • 어플리케이션 레벨에서 요청의 인증, 인가를 처리해준다.

  • Principal을 아이디, Credential을 비밀번호로 사용하는 Credential 기반의 인증 방식을 사용한다.

    • Principal(접근 주체): 보호받는 자원에 접근하는 대상
    • Credential(비밀번호): 자원에 접근하는 대상의 비밀번호
  • 보안과 관련해서 체계적으로 많은 옵션들을 제공해주기 때문에 개발자 입장에서는 보안 관련 로직을 일일이 작성하지 않아도 된다는 장점이 있다.

인증((Authentication)

유저가 누구인지 신원을 확인하는 절차

인증 방식

  • 세션-쿠키 방식 (Spring Security 사용)
  • JWT
  • 소셜 로그인 (OAuth2)

인가(Authorization)

인증된 사용자에게 요청한 자원에 접근이 가능한지를 결정하는 절차

  • 반드시 인증 -> 인가 순서로 진행

Filter

요청이 Dispatcher Servlet에 전달되기 전에 부가 작업을 처리할 수 있도록 톰캣(WAS)에서 지원해주는 기능

  • Spring Security는 필터를 기반으로 작동하여 인증과 권한에 관련된 처리를 진행한다.
  • Filter Chain을 통해 여러 필터가 연쇄적으로 동작하게 할 수 있다.

Spring Security 작동 방식

(Username, Password 기반의 form 인증일 경우)

  1. Http 요청 수신: 사용자가 로그인 정보와 함께 인증 요청을 보낸다.

  2. 토큰 생성: Authentication Filter가 요청을 받아서 UsernamePasswordAuthenticationToken(인증용 객체)을 생성한다.

  3. 토큰 전달: Authentication Filter로부터 토큰(UsernamePasswordAuthenticationToken)을 전달 받아 Authentication Manager에게 위임한다.

  4. 인증 요구: Authentication Manager가 Authentication Provider(들)을 조회하고 선택해서 토큰을 전달한다.

  5. 사용자 정보 전달: Authentication Provider는 토큰(인증용 객체)을 매개변수로 갖는 authenticate() 메소드를 호출해서 사용자 정보를 가져오고 UserDetailsService에 전달한다.

  6. DB 확인: UserDetailsService는 넘겨받은 사용자의 Username으로 loadUserByUsername() 메소드를 호출하여 DB에 있는 사용자의 정보를 UserDetails 형태로 가져온다. (사용자가 없으면 예외를 던진다.)

  7. 정보 비교: Authentication Provider는 UserDetails를 전달받고 해당 사용자의 정보와 토큰의 정보를 비교한다.

  8. 객체 반환: 비교 결과 사용자의 정보가 일치하면 사용자의 정보를 담은 Authentication 객체를 반환한다. (일치하지 않으면 예외를 던진다.)

  9. 객체 전달: Authentication Filter에Authentication 객체를 전달한다.

  10. 객체 저장: SecurityContextHolder가 세션 영역에 있는 SecurityContext에 전달받은 Authentication 객체를 저장한다.

Security 사용 방법

Dependency 추가

Gradle 사용 시 build.gradle의 dependencies에 다음 코드를 추가한다.

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-security'
    implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5'
}

(Thymeleaf를 사용한다면 한줄을 추가해야한다.)

이전 설정 방법

WebSecurityConfigurerAdapter를 상속하는 클래스에 인증과 인가에 관한 configure() 메소드를 Override해서 사용했다.

SecurityConfig.java

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
	...
   
    @Override
    protected void configure(HttpSecurity http) throws Exception{
    	http
            .authorizeHttpRequests((authz) -> authz
                .anyRequest().authenticated()
            )
            .httpBasic(withDefaults());
    }
}

Spring Boot 2.7+

Spring Security 5.7 부터 WebSecurityConfigurerAdapter를 상속받는 방법이 deprecated(권장하지 않으므로 지원 중단)되어 Spring Boot 2.7.0 버전부터는 securityFilterChain을 Bean으로 등록하는 방법을 사용한다.

SecurityConfig.java

@Configuration
public class SecurityConfig {
	...
    @Bean
    public DefaultSecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests((authz) -> authz
                .anyRequest().authenticated()
            )
            .httpBasic(withDefaults());
        return http.build();
    }
}

출처 및 참고

Spring Security 동작 원리
Spring Security 시큐리티 동작 원리 이해하기
Spring Security 설정 관련 공식 문서

0개의 댓글