간편로그인 관련 공부 중,
OAuth2.0 간편로그인을 붙이려면 Spring Scurity 내용도 알아야하기 때문에
간단하게 정리한 내용을 적어놓으려 한다.
공식 문서 내용이 많기 때문에 모든 내용을 적기보단 개요(?) 정도로만 정리해보려한다.
이 글을 보기 전에,
Spring Boot 동작방식, 서블릿, 필터, 인터프리터에 관한 글을 보는게 선행 된다면 이해하는데 도움이 된다고 생각한다.
(사실 Spring 으로 작업 하고 있다면 다들 알고 있겠지만... 공부해라 나...ㅋㅋ)
Spring Security 란?
Spring.io에서
'Spring Security는 일반적인 공격에 대한 인증, 권한 부여 및 보호 기능을 제공하는 프레임워크입니다 . 명령형 및 반응형 애플리케이션 모두를 보호하기 위한 최고 수준의 지원을 통해 Spring 기반 애플리케이션을 보호하기 위한 표준입니다.' 라고 정의 되어 있다.
현재 버전으로는 6 버전까지 나와 있으며,
7 버전도 배포 예정이라고 합니다.
Gradle
dependencies {
...
implementation 'org.springframework.boot:spring-boot-starter-security'
testImplementation 'org.springframework.security:spring-security-test'
...
}
제공 기능
- 모든 EndPoint 에 대한 인증 기능 제공
- Form 기반의 로그인, 로그아웃 플로우 제공
- CSRF, 세션 고정 공격 완화
- HttpServletRequest 의 인증 통합
- 인증 성공 및 실패 이벤트 게시
이외에도 제공되는 기능들이 있으니
더 확인하고 싶은 기능들은 Spring.io 에서 확인해주세요.
Architecture
Spring Security는 Servlet Filtter를 기반으로 작동 하는데,
여러 필터들을 엮어 FilterChain 이라고 합니다.
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
// do something before the rest of the application
chain.doFilter(request, response); // invoke the rest of the application
// do something after the rest of the application
}
Spring은 Servlet 컨테이너의 라이프사이클과 Spring의 ApplicationContext 간에 연결을 허용하는 DelegatingFilterProxy라는 Filter 구현을 제공합니다.
Servlet 컨테이너는 자체 표준을 사용하여 Filter 인스턴스를 등록할 수 있지만 Spring 정의 Bean을 인식하지 못합니다.
표준 Servlet 컨테이너 메커니즘을 통해 DelegatingFilterProxy를 등록할 수 있지만 Filter를 구현하는 Spring Bean에 모든 작업을 위임할 수 있습니다.
Spring Security의 서블릿 지원은 FilterChainProxy에 포함되어 있습니다.
FilterChainProxy는 Spring Security에서 제공하는 특별한 필터로서,
SecurityFilterChain을 통해 많은 Filter 인스턴스들에게 위임할 수 있도록 해줍니다.
FilterChainProxy는 Bean으로 사용되며, 일반적으로 DelegatingFilterProxy로 래핑됩니다.
Security Filter 들은 SecurityFilterChain API 를 사용하여 FilterChainProxy에 등록됩니다.
인증, 권한 부여, 공격 방어 등 다양한 목적으로 사용되며,
필터들은 정해진 순서대로 실행되어, 올바른 순서에 호출되도록 합니다.
예를 들어, 인증을 수행하는 필터가 권한 부여 필터보다 먼저 실행이 되는 것이 이러한 순서에 기인한 것입니다.
Spring.io 에는 필터의 순서까지 알 필요는 없다고 하지만, 알고 있으면 유용하다고 적혀있습니다.
(커스텀 필터 구현 시, 각 필터 용도에 맞게 분리 및 단일 책임으로 구성이 가능할 것이다.)
필터 작동 순서
1. CsrfFilter
2. AuthenticationFilter (UsernamePassword, Basic)
3. AuthorizationFilter
SecurityConfig 예시
SecurityConfig Class
@Configuration
@EnableWebSecurity
public class SecurityConfig {
private final CustomOAuth2UserService customOAuth2UserService;
private final AuthenticationFilter authenticationFilter;
private final OAuth2AuthenticationSuccessHandler oAuth2AuthenticationSuccessHandler;
private final OAuth2AuthenticationFailureHandler oAuth2AuthenticationFailureHandler;
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authorize -> authorize // 권한 지정
.requestMatchers("/").permitAll()
.requestMatchers("/login/**").permitAll()
.requestMatchers("/api/**").hasAuthority(Role.COMMON.getKey()))
// 세션 사용 설정
.sessionManagement(session -> session
// 세션을 사용하지 않겠다는 의미
.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
http
.oauth2Login(oauth2 -> oauth2
.userInfoEndpoint(userInfo -> userInfo
.userService(customOAuth2UserService))
.successHandler(oAuth2AuthenticationSuccessHandler)
.failureHandler(oAuth2AuthenticationFailureHandler)
);
http.addFilterBefore(authenticationFilter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}
}
Config 설정에 대한 FiterChain 은 위에 예시와 같이 작성되는데,
API 요청 시, 인증, 인가, 권한부여 등의 작업이 이루어지고
.authorizeHttpRequests() 에 정의된 API Path와 권한 설정에 따라 사용 또는 불가 처리가 이루어 진다.
마무리
이 외에도 정리할 내용이 많기는 하지만..
인증, 인가, 권한 OAuth2.0 ... 등등 정리해야 할게 너무 많아서
나중에 시간이 되면 추가적으로 정리내용을 올리거나,
직접 찾아보고 읽어보는 것도 좋다 생각 된다.
(특히 구조, 용어 의미!!)
참고 자료
Spring Security :: Spring Security
If you are ready to start securing an application see the Getting Started sections for servlet and reactive. These sections will walk you through creating your first Spring Security applications. If you want to understand how Spring Security works, you can
docs.spring.io
'DEV > Spring' 카테고리의 다른 글
[JPA] @JoinColumns 두 개 이상의 조인 컬럼 설정하기 (0) | 2023.08.06 |
---|---|
[Spring] 간편로그인 구현하기 (feat. 구글, 카카오) (0) | 2023.07.28 |
[Spring] Exception Handler (with. Spring Data Rest) (1) | 2023.07.12 |
[Spring] Spring Data Rest 란? (0) | 2023.07.10 |
[JPA] Repository 인터페이스 (0) | 2023.04.19 |