
DelegatingFilterProxy (μ€νλ§μμ λ±λ‘ν νν°)FilterChainProxy λ‘ μμ²μ μμFilterChainProxy λ λ΄λΆμ λ±λ‘λ SecurityFilterChain λͺ©λ‘μ κΈ°λ°μΌλ‘ μν리ν°μ μΈμ¦/μΈκ°μ κ°μ λ‘μ§μ μννλ€.
- DelegatingFilterProxy -> FilterChainProxy -> λ€μ WAS νν° νλ¦μΌλ‘ 볡κ·
- μ§μ μμ±νκ±°λ 컀μ€ν ν κ²½μ°λ κ±°μ μκΈ° λλ¬Έμ μ΄λ°κ΅¬μ‘°λ‘ μ§νλλ€ μ λλ§ μκΈ°λ‘ νμ.
μ€νλ§ μνλ¦¬ν° μμ‘΄μ±μ μΆκ°νλ©΄ μ°λ¦¬κ° λ°λ‘ μ€μ νμ§ μμ μ κΈ°λ³Έ 보μ μ€μ μ΄ μ μ©λ DefaultSecurityFilterChain μ΄ μλμΌλ‘ λ±λ‘λλ€.
컀μ€ν°λ§μ΄μ§μ΄ νμνλ€λ©΄ SecurityFilterChain μ λ°ννλ @Bean λ©μλλ₯Ό μ μν΄ μ§μ λ±λ‘ν μ μλ€.
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain1(HttpSecurity httpSecurity) throws Exception {
return httpSecurity
.authorizeHttpRequests(auth -> auth
.requestMatchers("/admin/**").permitAll()
.anyRequest().authenticated())
.build();
}
}
SecurityFilterChain μ Nκ°λ₯Ό λ±λ‘ν μλ μμΌλ©° FilterChainProxy λ κ° νν°μ²΄μΈμ RequestMatcher λ₯Ό μμλλ‘ κ²μ¬νμ¬
κ°μ₯ λ¨Όμ λ§€μΉλλ νλμ 체μΈλ§ μ νν΄ μ€ννλ€.
λ°λΌμ λ±λ‘μμκ° λ§€μ° μ€μνλ©° νμμ @Order μ΄λ
Έν
μ΄μ
μ ν΅ν΄ λͺ
μμ μΌλ‘ μμλ₯Ό μ μ΄ν μ μλ€.
@Orderλ₯Ό λͺ μνμ§ μμΌλ©΄ λ±λ‘λ μμλλ‘ κ²μ¬λλ―λ‘(/**)μ κ°μ λ무 λμ matcher κ° μμ μ€λ©΄ λ€λ₯Έ 체μΈμ΄ μλνμ§ μμ μ μλ€.
μ€μ μ΄λ°μ .securityMatcher() λ₯Ό μ¬μ©ν΄ μ΄ μ²΄μΈμ΄ μ΄λ€ μμ²μ λ§€μΉλ μ§ μ§μ ν μ λ μλ€.
@Bean
public SecurityFilterChain adminFilterChain(HttpSecurity http) throws Exception {
return http
.securityMatcher("/admin/**") // RequestMatcher μν : μ΄ μ²΄μΈμ /admin/** μμ²μλ§ μ μ©νλ€λ λ»
.authorizeHttpRequests(auth -> auth.anyRequest().authenticated())
.build();
}
- DisableEncodeUrlFilter
- URLλ‘ κ°μ£Όλμ§ μλ λΆλΆμ ν¬ν¨νμ§ μλλ‘ μ€μ
- WebAsyncManagerIntegrationFilter
- Spring MVC μ
@Async,Callable,DeferredResultκ°μ λΉλκΈ° μ²λ¦¬μ μνλ¦¬ν° μ»¨ν μ€νΈλ₯Ό μ°κ²°- SecurityContextHolderFilter
- μΈμ¦λ μ¬μ©μ μ 보λ₯Ό
SecurityContextHolderμ μ μ₯νκ³ μ°λ λ κ° λ³΄μ 컨ν μ€νΈ μ μ§- HeaderWriterFilter
- 보μ κ΄λ ¨ HTTP ν€λλ₯Ό μλ΅μ μΆκ°(μ: X-Content-Type-Options, X-Frame-Options, Cache-Control)
- μ€νλ§ μν리ν°μ ν€λ κ΄λ ¨ μ€μ μ λλΆλΆ μ¬κΈ°μ μ²λ¦¬
- CorsFilter
- κ΅μ°¨ μΆμ² μμ²(CORS)μ λν μ²λ¦¬
- CsrfFilter
- CSRF(Cross Site Request Forgery) 곡격μ λ°©μ§νκΈ° μν νν°
- μλ²κ° μ 곡ν ν ν°κ³Ό ν΄λΌμ΄μΈνΈ μμ²μ ν ν°μ λΉκ΅
- LogoutFilter
/logoutμμ²μ μ²λ¦¬νλ μμμ - λ‘κ·Έμμ μ μΈμ 무ν¨ν,
SecurityContextμ΄κΈ°ν, μΈμ¦ μΏ ν€ μμ λ±- κΈ°λ³Έμ
GET: /logoutμ΄λ©° 컀μ€ν°λ§μ΄μ§ κ°λ₯νλ€.- UsernamePasswordAuthenticationFilter
/loginμμ²μ μ²λ¦¬νλ νν°- μ¬μ©μκ° μ μΆν
usernameκ³Όpasswordλ₯Ό μΆμΆν΄AuthenticationManagerμ μΈμ¦μ μμ²νμ¬ μ±κ³΅μSecurityContextμ μΈμ¦μ 보 μ μ₯- DefaultLoginPageGeneratingFilter
- λ³λμ λ‘κ·ΈμΈ νμ΄μ§λ₯Ό λ§λ€μ§ μμμ λ κΈ°λ³Έ λ‘κ·ΈμΈ νμ΄μ§
GET: /loginμ μμ±νμ¬ μλ΅- λΉνμ±ννκ±°λ 컀μ€ν°λ§μ΄μ§ κ°λ₯
- DefaultLogoutPageGeneratingFilter
- κΈ°λ³Έ λ‘κ·Έμμ νμ΄μ§ μμ±
GET: /logout- 컀μ€ν°λ§μ΄μ§ κ°λ₯
- BasicAuthenticationFilter
Authorization: Basic μ΄νν ν°ν€λκ° ν¬ν¨λ μμ²μ μ²λ¦¬- HTTP Basic μΈμ¦ κΈ°λ°μΌλ‘ ν€λμμ
username/passwordμΆμΆ ν μΈμ¦ μ²λ¦¬- RequestCacheAwareFilter
- μΈμ¦ ν μλ μ κ·Όνλ €λ URLμ΄ μμ κ²½μ° ν΄λΉ URLλ‘ redirect
- μΈμ¦ λμ€ μμ²μ΄ μΈν°μ νΈλλ©΄ μ±κ³΅ ν μμ²μΌλ‘ 리λ€μ΄λ νΈνλλ‘ λμμ€
- SecurityContextHolderAwareRequestFilter
- μλΈλ¦Ώ APIμμ μ 곡νλ 보μ κ΄λ ¨ λ©μλλ€μ μνλ¦¬ν° μ»¨ν μ€νΈμ μ°λ
- AnonymousAuthenticationFilter
- μΈμ¦λμ§ μμ μμ²μ λν΄ μλμΌλ‘
μ΅λͺ μ¬μ©μλ‘ μ€μ - SecurityContext κ° λΉμ΄μμ κ²½μ° μ΅λͺ μΈμ¦ κ°μ²΄(AnonymousAuthenticationToken)λ₯Ό μ½μ
- λ°λΌμ μν리ν°λ νμ μΈμ¦ κ°μ²΄λ₯Ό κ°μ§κ³ λμ
- ExceptionTranslationFilter
- μΈμ¦ μ€ν¨λ μΈκ° μ€ν¨ μμΈμ λν μ μ ν μ²λ¦¬ μν
- μΈμ¦ μ€ν¨ -> λ‘κ·ΈμΈ νμ΄μ§λ‘ redirect
- μΈκ° μ€ν¨ -> 403 μλ¬ λ°ν
- μνλ¦¬ν° νν° μ€
μμΈ νΈλ€λ§μ ν΅μ¬ νν°- AuthorizationFilter
- μ΅μ’ μΈκ° λ‘μ§ μν : κ²½λ‘, κΆν, μν λ± μ μ± μ λ°λΌ μ κ·Ό κ°λ₯ μ¬λΆ νλ¨
- 컨νΈλ‘€λ¬ μ€ν μ μΈκ° λ‘μ§μ λ°λΌ μ κ·Όμ νμ©νκ±°λ μ°¨λ¨
@Bean
public SecurityFilterChain customFilterChain(HttpSecurity http) throws Exception {
http
// λΉνμ±ν μμ
.cors(cors -> cors.disable()) // CorsFilter λΉνμ±ν
.csrf(csrf -> csrf.disable()) // CsrfFilter λΉνμ±ν
.httpBasic(httpBasic -> httpBasic.disable()) // BasicAuthenticationFilter λΉνμ±ν
// νμ±ν μμ
.formLogin(withDefaults()) // UsernamePasswordAuthenticationFilter νμ±ν (κΈ°λ³Έ λ‘κ·ΈμΈ νΌ)
.logout(withDefaults()); // LogoutFilter νμ±ν (κΈ°λ³Έ λ‘κ·Έμμ μ²λ¦¬)
return http.build();
}
csrf, formLogin, logout λ± μΌλΆ νν°λ μλ΅νλ©΄ μλμΌλ‘ νμ±νλλ κ²½μ°λ μμΌλ©°
λͺ
μμ μΌλ‘ νμ±ν νκΈ° μν΄μ withDefaults() λλ 컀μ€ν
μ€μ μ λ£μ΄μ£Όλ©΄ λλ€.
μ΄μ²λΌ κΈ°λ³Έμ μΌλ‘ λ©μλλ₯Ό ν΅ν΄ νμ±/λΉνμ±νλ₯Ό μ‘°μ ν μ μλ€.
withDefaults()λ?
- formLogin(withDefaults()) == formLogin(form -> {})
- λ΄λΆμ μΌλ‘λ λΉ μ€μ λΈλ‘μ λ£λ κ²κ³Ό κ°μμ κΈ°λ³Έ λμμ νμ±ν νλ€λ κ²μ λ»νλ€.
- νΉμ νν° μ΄μ
- .addFilterBefore(μΆκ°ν νν°, κΈ°μ‘΄νν°.class)
- νΉμ νν° μμΉ
- .addFilterAt(μΆκ°ν νν°, κΈ°μ‘΄νν°.class)
- νΉμ νν° μ΄ν
- .addFilterAfter(μΆκ°ν νν°, κΈ°μ‘΄νν°.class)
2νΈμ SecurityContextHolder λ‘ μ΄μ΄μ§λλ€.
- https://www.youtube.com/@xxxjjhhh
κ°λ°μ μ λ―Έλ μ νλΈ - μ€νλ§ μνλ¦¬ν° λ΄λΆκ΅¬μ‘° 1 ~ 5