스프링 기반의 어플리케이션의 보안을 담당하는 프레임워크
어플리케이션 레벨에서 요청의 인증
, 인가
를 처리해준다.
Principal
을 아이디, Credential
을 비밀번호로 사용하는 Credential 기반의 인증 방식을 사용한다.
- Principal(접근 주체): 보호받는 자원에 접근하는 대상
- Credential(비밀번호): 자원에 접근하는 대상의 비밀번호
보안과 관련해서 체계적으로 많은 옵션들을 제공해주기 때문에 개발자 입장에서는 보안 관련 로직을 일일이 작성하지 않아도 된다는 장점이 있다.
유저가 누구인지 신원을 확인하는 절차
인증 방식
인증된 사용자에게 요청한 자원에 접근이 가능한지를 결정하는 절차
요청이 Dispatcher Servlet에 전달되기 전에 부가 작업을 처리할 수 있도록 톰캣(WAS)에서 지원해주는 기능
Filter Chain
을 통해 여러 필터가 연쇄적으로 동작하게 할 수 있다.(Username, Password 기반의 form 인증일 경우)
Http 요청 수신: 사용자가 로그인 정보와 함께 인증 요청을 보낸다.
토큰 생성: Authentication Filter가 요청을 받아서 UsernamePasswordAuthenticationToken(인증용 객체)을 생성한다.
토큰 전달: Authentication Filter로부터 토큰(UsernamePasswordAuthenticationToken)을 전달 받아 Authentication Manager에게 위임한다.
인증 요구: Authentication Manager가 Authentication Provider(들)을 조회하고 선택해서 토큰을 전달한다.
사용자 정보 전달: Authentication Provider는 토큰(인증용 객체)을 매개변수로 갖는 authenticate() 메소드를 호출해서 사용자 정보를 가져오고 UserDetailsService에 전달한다.
DB 확인: UserDetailsService는 넘겨받은 사용자의 Username으로 loadUserByUsername() 메소드를 호출하여 DB에 있는 사용자의 정보를 UserDetails 형태로 가져온다. (사용자가 없으면 예외를 던진다.)
정보 비교: Authentication Provider는 UserDetails를 전달받고 해당 사용자의 정보와 토큰의 정보를 비교한다.
객체 반환: 비교 결과 사용자의 정보가 일치하면 사용자의 정보를 담은 Authentication 객체를 반환한다. (일치하지 않으면 예외를 던진다.)
객체 전달: Authentication Filter에Authentication 객체를 전달한다.
객체 저장: SecurityContextHolder가 세션 영역에 있는 SecurityContext에 전달받은 Authentication 객체를 저장한다.
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 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 설정 관련 공식 문서