Spring Security

์ด ๋‚ด์šฉ์€ Spring Security Architecture ๊ณต์‹ ๋ฌธ์„œ์ž…๋‹ˆ๋‹ค. Servlet์„ ๊ธฐ๋ฐ˜์œผ๋กœํ•˜๋Š” ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ ์•„ํ‚คํ…์ณ์— ๋Œ€ํ•œ ๋‚ด์šฉ์„ ๋‹ค๋ฃจ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

Architecture

Review of Filters

์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ์˜ Servlet์€ Servlet Filter ๋ ˆ๋ฒจ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ๋‹ค. ์•„๋ž˜ ์ด๋ฏธ์ง€๋Š” HTTP request์— ๋Œ€ํ•œ ํ•ธ๋“ค๋Ÿฌ์˜ ์ผ๋ฐ˜์ ์ธ ๊ตฌ์กฐ๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค.

ํด๋ผ์ด์–ธํŠธ๋Š” ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ request๋ฅผ ๋ณด๋‚ด๊ณ  ์ปจํ…Œ์ด๋„ˆ๋Š” Filter์™€ Servlet์„ ํฌํ•จํ•˜๋Š” FilterChain์„ ์ƒ์„ฑํ•œ๋‹ค. ์ด ๋•Œ request URI ๊ฒฝ๋กœ์— ๊ธฐ๋ฐ˜ํ•ด HttpServletRequest๋ฅผ ์ฒ˜๋ฆฌํ•œ๋‹ค. ์Šคํ”„๋ง MVC ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ Servlet์€ DispatcherServlet์˜ ๊ตฌํ˜„์ฒด์ด๋‹ค.

ํ•˜๋‚˜์˜ Servlet์€ ๊ธฐ๊ปํ•ด์•ผ 1๊ฐœ์˜ HttpServletRequest์™€ HttpServletResponse๋ฅผ ๋‹ค๋ฃฌ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ 2๊ฐœ ์ด์ƒ์˜ Filter๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค์Œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

  • ๋‹ค์Œ Filter๊ฐ€ ํ˜ธ์ถœ๋˜์ง€ ์•Š๋„๋ก ํ•œ๋‹ค. ์ด ๊ฒฝ์šฐ Filter๋Š” HttpServletResponse๋ฅผ ์ž‘์„ฑํ•œ๋‹ค.

  • ๋‹ค์Œ Filter์™€ Servlet์—์„œ ์‚ฌ์šฉ๋˜๋Š” HttpServletRequest ๋˜๋Š” HttpServletResponse๋ฅผ ์ˆ˜์ •ํ•œ๋‹ค.

Filter์˜ ํšจ๊ณผ๋Š” ์ด๋ฅผ ํ†ต๊ณผํ•˜๋Š” FilterChain์— ์žˆ๋‹ค.

ํ•˜๋‚˜์˜ Filter๋Š” ๋‹ค์Œ Filter ๊ตฌํ˜„์ฒด์™€ Servlet์—๋งŒ ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ ๊ฐ๊ฐ์˜ Filter๊ฐ€ ์‚ฌ์šฉ๋˜๋Š” ์ˆœ์„œ๋Š” ์ƒ๋‹นํžˆ ์ค‘์š”ํ•˜๋‹ค.

DelegatingFilterProxy

์Šคํ”„๋ง์€ DelegatingFlterProxy ๋ฅผ ์ œ๊ณตํ•œ๋‹ค. ์ด๋Š” Servlet ์ปจํ…Œ์ด๋„ˆ์™€ ์Šคํ”„๋ง์˜ Application Context ์‚ฌ์ด๋ฅผ ์—ฐ๊ฒฐํ•ด์ค€๋‹ค. Servlet ์ปจํ…Œ์ด๋„ˆ๋Š” Servlet ์ŠคํŽ™์ด๊ธฐ ๋•Œ๋ฌธ์— ์Šคํ”„๋ง์—์„œ ์ •์˜๋œ ๋นˆ์„ ์ฃผ์ž…๋ฐ›์•„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค.

์ด ๋•Œ DelegatingFilterProxy๋ฅผ ํ†ตํ•ด ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์—์„œ ์กด์žฌํ•˜๋Š” ํŠน์ • Bean์„ ์ฐพ์•„ ์š”์ฒญ์„ ์œ„์ž„ํ•œ๋‹ค.

FilterChainProxy

FilterChainProxy ๋Š” ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ์— ์˜ํ•ด ์ œ๊ณต๋˜๋Š” ํŠน๋ณ„ํ•œ ํ•„ํ„ฐ์ด๋‹ค. SecurityFilterChain์„ ํ†ตํ•ด ๋งŽ์€ ํ•„ํ„ฐ ์ธ์Šคํ„ด์Šค๋ฅผ ์œ„์ž„ํ•œ๋‹ค.FilterChainProxy๋„ Bean์ด๋ฏ€๋กœ DelegatingFilterProxy๋กœ wrapping๋œ๋‹ค.

SecurityFilterChain

SecurityFilterChain์€ ํ˜„์žฌ request์—์„œ ์–ด๋–ค ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ Filter ์ธ์Šคํ„ด์Šค๊ฐ€ ์‚ฌ์šฉ๋˜์–ด์•ผ ํ• ์ง€ ๊ฒฐ์ •ํ•˜๊ธฐ ์œ„ํ•ด FilterChainProxy์— ์˜ํ•ด์„œ ์‚ฌ์šฉ๋œ๋‹ค.

SecurityFilterChain ์•ˆ์˜ Security Filter๋“ค์€ ์ผ๋ฐ˜์ ์œผ๋กœ Bean์ด๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ DelegatingFilterProxy ๋Œ€์‹ ์— FilterChainProxy ๋กœ ๋“ฑ๋ก๋œ๋‹ค.

FilterChainProxy ๋Š” Servlet ์ปจํ…Œ์ด๋„ˆ๋‚˜ DelegatingFilterProxy์— ์ง์ ‘์ ์œผ๋กœ ๋“ฑ๋กํ•˜๋Š” ๊ฒƒ์— ๋งŽ์€ ์ด์ ์„ ์ œ๊ณตํ•œ๋‹ค.

  1. ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ Servlet์˜ ์‹œ์ž‘์ ์„ ์ œ๊ณตํ•œ๋‹ค. โ‡’ trouble shooting์— ์šฉ์ด

  2. ๋ณด์ด์ง€ ์•Š๋Š” ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค. (HttpFireWall ๋“ฑ)

  3. SecurityFilterChain์ด invoke๋˜๋Š” ์‹œ์ ์„ ๊ฒฐ์ •ํ•˜๋Š” ๋ฐ์— ์œ ์—ฐ์„ฑ์„ ์ œ๊ณตํ•œ๋‹ค.

    URL์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๋™์ž‘ํ•˜๋Š”๋ฐ, RequestMathcer interface๋ฅผ ์‚ฌ์šฉํ•จ์œผ๋กœ์จ invocation์„ ๊ฒฐ์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

์œ„ ๊ทธ๋ฆผ์—์„œ FilterChainProxy ๊ฐ€ ์–ด๋–ค SecurityFilterChain์ด ์‚ฌ์šฉ๋ ์ง€ ๊ฒฐ์ •ํ•œ๋‹ค. ๋ถ€ํ•ฉํ•˜๋Š” ์ฒซ๋ฒˆ์งธ SecurityFilterChain ๋งŒ ์ ์šฉ๋œ๋‹ค. ๋งŒ์•ฝ /api/message/ ๊ฐ€ ์š”์ฒญ๋œ๋‹ค๋ฉด, /api/** ํŒจํ„ด์˜ SecurityFilterChain0SecurityFilterChain_0์ด ๋งค์น˜๋œ๋‹ค. ๋”ฐ๋ผ์„œ ๋น„๋กSecurityFilterChainnSecurityFilterChain_n๋„ ๋งค์น˜๋ ์ง€๋ผ๋„, SecurityFilterChain0SecurityFilterChain_ 0 ์ด ์‹คํ–‰๋œ๋‹ค.

๋งŒ์•ฝ /essages/ URL์ด ์š”์ฒญ๋œ๋‹ค๋ฉด SecurityFilterChain0SecurityFilterChain_0๊ณผ๋Š” ๋งค์น˜๋˜์ง€ ์•Š๋Š”๋‹ค. ๋”ฐ๋ผ์„œ FilterChainProxy ๋Š” ๊ฐ๊ฐ์˜ SecurityFiterChain ์„ ์‹œ๋„ํ•ด๋ณด๋‹ค๊ฐ€ ๊ฒฐ๊ตญ SecurityFilterChainnSecurityFilterChain_n์ด ์ ์šฉ๋œ๋‹ค.

SecurityFilterChain0SecurityFilterChain_0์€ 3๊ฐœ์˜ Filter ์ธ์Šคํ„ด์Šค๋กœ ๊ตฌ์„ฑ๋˜์–ด์žˆ๊ณ , SecurityFilterChainnSecurityFilterChain_n์€ 4๊ฐœ์˜ ํ•„ํ„ฐ ์ธ์Šคํ„ด์Šค๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋‹ค. ๊ฐ๊ฐ์˜ SecurityFilterChain ์€ ํŠน๋ณ„ํ•˜๊ณ  ๋…๋ฆฝ์ ์œผ๋กœ ๊ตฌ์„ฑ๋  ์ˆ˜ ์žˆ๋‹ค. ์‚ฌ์‹ค SecurityFilterChain ์€ ๋งŒ์•ฝ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์ด Spring Security๊ฐ€ ํŠน์ • request๋ฅผ ๋ฌด์‹œํ•˜๊ธธ ์›ํ•œ๋‹ค๋ฉด, Filter ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ€์ง€์ง€ ์•Š๊ฒŒ ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

Security Filters

Security Filter๋Š” SecurityFilterChain API์™€ ํ•จ๊ป˜ FilterChainProxy์— ์‚ฝ์ž…๋œ๋‹ค. ์ด Filter๋“ค์€ ์ธ์ฆ, ์ธ๊ฐ€ ๋“ฑ ๋‹ค์–‘ํ•œ ๋ชฉ์ ์œผ๋กœ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋‹ค. Filter๋Š” ์›ํ•˜๋Š” ์ˆœ์„œ๋กœ ์‹คํ–‰๋˜๊ธฐ ์œ„ํ•ด ํŠน์ •ํ•œ ์ˆœ์„œ๋กœ ์‹คํ–‰๋œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์ธ์ฆ์„ ์ˆ˜ํ–‰ํ•˜๋Š” Filter๋Š” ์ธ๊ฐ€๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” Filter ์ „์— ์‹คํ–‰๋˜์–ด์•ผ ํ•œ๋‹ค. Spring Security์˜ Filter๋“ค์˜ ์ˆœ์„œ๋ฅผ ์•„๋Š” ๊ฒƒ์€ ์ผ๋ฐ˜์ ์œผ๋กœ ํ•„์š”ํ•œ ๊ฒƒ์€ ์•„๋‹ˆ์ง€๋งŒ, ์ˆœ์„œ๋ฅผ ์•„๋Š” ๊ฒƒ์ด ๋„์›€์ด ๋˜๋Š” ๋•Œ๊ฐ€ ์žˆ๋‹ค.

https://github.com/spring-projects/spring-security/blob/6.3.1/config/src/main/java/org/springframework/security/config/annotation/web/builders/FilterOrderRegistration.java

security configuration์˜ ํ•œ๊ฐ€์ง€ ์˜ˆ๋ฅผ ๋“ค์–ด๋ณด์ž.

์œ„ Configuration์€ ๋‹ค์Œ์˜ Filter ์ˆœ์„œ๋ฅผ ๊ฐ€์ง„๋‹ค.

  • CsrfFilter โ† HttpSecurity#csrf

    • CsrfFilter ๋Š” CSRF ๊ณต๊ฒฉ์„ ๋ง‰๊ธฐ ์œ„ํ•ด ์‹คํ–‰๋œ๋‹ค.

  • UsernamePasswordAuthenticationFilter โ† HttpSecurity#formLogin

  • BasicAuthenticationFilter โ† HttpSecurity#httpBasic

    • request๋ฅผ authenticateํ•˜๊ธฐ ์œ„ํ•ด ์‹คํ–‰๋œ๋‹ค.

  • AuthorizationFilter โ† HttpSecurity#authorizeHttpRequests

    • AuthorizationFilter ๋Š” request๋ฅผ authorize ํ•˜๊ธฐ ์œ„ํ•ด ์‹คํ–‰๋œ๋‹ค.

์œ„์˜ ๋‚˜์™€์žˆ๋Š” Filter ์™ธ์— ๋‹ค๋ฅธ Filter ์ธ์Šคํ„ด์Šค๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ๋‹ค. ํŠน์ • request์— ์‹คํ–‰๋˜๋Š” Filter ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ณด๊ณ  ์‹ถ๋‹ค๋ฉด, print ํ•ด์„œ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

Printing the Security Filters

๊ฐ€๋”์€ ํŠน์ • request์— ์‹คํ–‰๋˜๋Š” Security Filter ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ณด๋Š”๊ฒŒ ์œ ์šฉํ•  ๋•Œ๋„ ์žˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์ถ”๊ฐ€ํ•œ Filter๊ฐ€ ํ™•์‹คํžˆ ์‹คํ–‰๋˜๋Š”์ง€ ํ™•์ธํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ํ™•์ธํ•˜๋ฉด ๋œ๋‹ค.

Filter ๋ฆฌ์ŠคํŠธ๋Š” ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์‹คํ–‰๋  ๋•Œ INFO ๋ ˆ๋ฒจ์—์„œ ํ”„๋ฆฐํŠธ๋œ๋‹ค. ๋”ฐ๋ผ์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ฝ˜์†”์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

๋˜๋Š” ์ง์ ‘ logging์„ ์ด์šฉํ•ด์„œ ํ™•์ธํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

Adding a Custom Filter to the Filter Chain

๋Œ€๋ถ€๋ถ„ ๊ธฐ๋ณธ Security Filter๋“ค์€ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์— security๋ฅผ ์ œ๊ณตํ•˜๊ธฐ์— ์ถฉ๋ถ„ํ•˜๋‹ค. ํ•˜์ง€๋งŒ Custom Filter๋ฅผ security filter chain์— ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ์„ ๋•Œ๊ฐ€ ์กด์žฌํ•  ๊ฒƒ์ด๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, tenant id header๋ฅผ ๊ฐ€์ ธ๊ฐ€์„œ ํ˜„์žฌ ์œ ์ €๊ฐ€ ํ•ด๋‹น tenant์— ์ ‘๊ทผ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” Filter๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ๋‹ค๊ณ  ํ•ด๋ณด์ž. ์šฐ๋ฆฌ๋Š” ํ˜„์žฌ ์œ ์ €๋ฅผ ์•Œ ํ•„์š”๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์–ด๋””์— Filter๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ• ์ง€ ์•Œ ์ˆ˜ ์žˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์ธ์ฆ Filter ๋’ค์—๋‹ค๊ฐ€ ์ถ”๊ฐ€ํ•ด์•ผ ํ•œ๋‹ค.

์ƒ˜ํ”Œ ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋™์ž‘ํ•œ๋‹ค.

  1. request header๋กœ๋ถ€ํ„ฐ tenant id๋ฅผ ์–ป๋Š”๋‹ค.

  2. ํ˜„์žฌ ์œ ์ €๊ฐ€ tenant id์— ์ ‘๊ทผ ๊ถŒํ•œ์ด ์žˆ๋Š”์ง€ ๊ฒ€์‚ฌํ•œ๋‹ค.

  3. ์ ‘๊ทผ ๊ถŒํ•œ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๋ฉด ๋‚˜๋จธ์ง€ ํ•„ํ„ฐ๋ฅผ ์‹คํ–‰ํ•œ๋‹ค.

  4. ์ ‘๊ทผ ๊ถŒํ•œ์ด ์—†๋‹ค๋ฉด AccessDeniedException ์„ ๋˜์ง„๋‹ค.

Filter ๋ฅผ implements ํ•˜๋Š” ๋Œ€์‹ , OncePerRequestFilter ๋ฅผ extends ํ•  ์ˆ˜๋„ ์žˆ๋‹ค. OncePerRequestFilter ๋Š” filter์˜ base class์ด๊ณ , request ๋‹น 1๋ฒˆ๋งŒ ์‹คํ–‰๋œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  HttpServletRequest ์™€ HttpServletResponse ๋ฅผ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋ฐ›๋Š” doFilterInternal ๋ฉ”์†Œ๋“œ๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

์ด์ œ, Filter๋ฅผ security filter chain์— ์ ์šฉํ•ด๋ณด์ž.

AuthorizationFilter ์ „์— TenantFilter๋ฅผ ์ถ”๊ฐ€ํ•˜๊ธฐ ์œ„ํ•ด HttpSecurity#addFilterBefore ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

์ด ํ•„ํ„ฐ๋ฅผ AythorizationFilter ์ „์— ์ถ”๊ฐ€ํ•จ์œผ๋กœ์จ TenantFilter ๊ฐ€ authentication ํ•„ํ„ฐ ๋’ค์— ์‹คํ–‰ํ•˜๊ฒŒ ํ–ˆ๋‹ค. ๋˜ํ•œ ํŠน์ • ํ•„ํ„ฐ ๋’ค์— ์ƒˆ๋กœ์šด ํ•„ํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ธฐ ์œ„ํ•ด HttpSecurity#addFilterAfter ๋ฅผ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜, ํŠน์ • ํ•„ํ„ฐ ํฌ์ง€์…˜์— ์ƒˆ๋กœ์šด ํ•‰๋Ÿฌ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ธฐ ์œ„ํ•ด HttpSecurity#addFilterAt ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

์ปค์Šคํ…€ ํ•„ํ„ฐ๋ฅผ ์Šคํ”„๋ง ๋นˆ์œผ๋กœ ์„ ์–ธํ•  ๋•Œ ์ฃผ์˜ํ•ด์•ผ ํ•œ๋‹ค. ํ•„ํ„ฐ์— @Component ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ configuration์— ๋นˆ์œผ๋กœ ์„ ์–ธํ•˜๊ฑฐ๋‚˜ ๋‘˜ ์ค‘์— ํ•˜๋‚˜๋งŒ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค. ์Šคํ”„๋ง ๋ถ€ํŠธ๋Š” ์ž๋™์ ์œผ๋กœ ์ด๊ฒƒ์„ ๋‚ด์žฅ๋œ ์ปจํ…Œ์ด๋„ˆ์— ๋“ฑ๋กํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ํ•„ํ„ฐ๊ฐ€ ์ปจํ…Œ์ด๋„ˆ์— ์˜ํ•ด 1๋ฒˆ, ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ์— ์˜ํ•ด์„œ 1๋ฒˆ ์ด 2๋ฒˆ invoke๋  ์ˆ˜ ์žˆ๋‹ค.

๋งŒ์•ฝ DI์˜ ์ด์ ์„ ์–ป๊ธฐ ์œ„ํ•ด Spring Bean์œผ๋กœ ํ•„ํ„ฐ๋ฅผ ๋“ฑ๋กํ•˜๋ฉด์„œ ์ค‘๋ณต invocation์„ ํ”ผํ•˜๋ ค๋ฉด, FilterRegistrationBean ์œผ๋กœ ์„ ์–ธํ•˜๊ณ  enabled ์„ false๋กœ ์„ค์ •ํ•จ์œผ๋กœ์จ ์Šคํ”„๋ง ๋ถ€ํŠธ๊ฐ€ ํ•„ํ„ฐ๋ฅผ ์ปจํ…Œ์ด๋„ˆ์— ๋“ฑ๋กํ•˜์ง€ ์•Š๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋‹ค.

Handling Security Exceptions

ExceptionTranslationFilter ๋Š” AccessDeniedException ๊ณผ AuthenticationException ์„ HTTP response ์œผ๋กœ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ๋‹ค. ExceptionTranslationFilter ๋Š” Security Filter ์ค‘ ํ•˜๋‚˜๋กœ FilterChainProxy์— ์‚ฝ์ž…๋œ๋‹ค.

์•„๋ž˜ ์ด๋ฏธ์ง€๋Š” ExceptionTranslationFilter ์™€ ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ์™€์˜ ๊ด€๊ณ„๋ฅผ ๋ณด์—ฌ์ค€๋‹ค.

  1. ExceptionTranslationFilter ๊ฐ€ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋‚˜๋จธ์ง€ ๋ถ€๋ถ„์„ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•ด FilterChain.doFilter(request, response) ๋ฅผ ์‹คํ–‰ํ•œ๋‹ค.

  2. ๋งŒ์•ฝ ์œ ์ €๊ฐ€ ์ธ์ฆ๋˜์ง€ ์•Š์•˜๊ฑฐ๋‚˜ AuthenticationException ์ธ ๊ฒฝ์šฐ, Authentication์„ ์‹œ์ž‘ํ•œ๋‹ค.

    1. SecurityContextHolder๊ฐ€ ์ดˆ๊ธฐํ™”๋œ๋‹ค.

    2. HttpServletRequest ๋Š” ์ธ์ฆ์ด ์„ฑ๊ณตํ•˜๋ฉด original request๋ฅผ replayํ•˜๋Š”๋ฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์ €์žฅ๋œ๋‹ค.

    3. AutenticationEntryPoint ๋Š” ํด๋ผ์ด์–ธํŠธ๋กœ๋ถ€ํ„ฐ credential์„ ์š”์ฒญํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธํ•˜๊ฑฐ๋‚˜, WWW-Authenticate ํ—ค๋”๋ฅผ ๋ณด๋‚ผ ์ˆ˜ ์žˆ๋‹ค.

  3. AccessDeniedException ์ธ ๊ฒฝ์šฐ, ์ ‘๊ทผ์„ ์ œํ•œํ•œ๋‹ค. AccessDeniedHandler ๊ฐ€ ์ ‘๊ทผ์„ ์ œํ•œํ•˜๊ธฐ ์œ„ํ•ด ์‹คํ–‰๋œ๋‹ค.

๋งŒ์•ฝ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์ด AccessDeniedException ์ด๋‚˜ AuthenticationException ์„ ์ผ์œผํ‚ค์ง€ ์•Š๋Š”๋‹ค๋ฉด, ExceptionTranslationFilter ๋Š” ์•„๋ฌด๊ฒƒ๋„ ํ•˜์ง€ ์•Š๋Š”๋‹ค.

ExceptionTranslationFilter ์˜ ์˜์‚ฌ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์žˆ๋‹ค.

  1. FilterChain.doFilter(request, response) ๋Š” ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋‚˜๋จธ์ง€ ๋ถ€๋ถ„์„ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™๋‹ค. ๋งŒ์•ฝ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋‚˜๋จธ์ง€ ๋ถ€๋ถ„์ด AuthenticationException ๋˜๋Š” AccessDeniedException ์„ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค๋ฉด, ์—ฌ๊ธฐ์„œ ์ฒ˜๋ฆฌ๋œ๋‹ค.

  2. ๋งŒ์•ฝ ์œ ์ €๊ฐ€ ์ธ์ฆ๋˜์ง€ ์•Š์•˜๊ฑฐ๋‚˜ AuthenticationException ์ธ ๊ฒฝ์šฐ, Authentication์„ ์‹œ์ž‘ํ•œ๋‹ค.

  3. ๊ทธ๋ ‡์ง€ ์•Š๋‹ค๋ฉด, ์ ‘๊ทผ์„ ์ œํ•œํ•œ๋‹ค.

Saving Requests Between Authentication

request๊ฐ€ authentication์„ ๊ฐ€์ง€๊ณ  ์žˆ์ง€ ์•Š๊ณ  authentication์„ ์š”๊ตฌํ•˜๋Š” ๋ฆฌ์†Œ์Šค์ผ ๋•Œ, ์ธ์ฆ์ด ์„ฑ๊ณตํ•œ ํ›„ re-requestํ•˜๊ธฐ ์œ„ํ•ด ์ธ์ฆ๋œ ๋ฆฌ์†Œ์Šค์— ๋Œ€ํ•œ ์š”์ฒญ์„ ์ €์žฅํ•  ํ•„์š”๊ฐ€ ์žˆ๋‹ค. ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ์—์„œ ์ด ๊ฒƒ์€ RequestCache ๊ตฌํ˜„์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” HttpServletRequest ๋ฅผ ์ €์žฅํ•จ์œผ๋กœ์จ ์ด๋ค„์ง„๋‹ค.

RequestCache

HttpServletRequest ๋Š” RequestCache ์— ์ €์žฅ๋œ๋‹ค. ์œ ์ €๊ฐ€ ์„ฑ๊ณต์ ์œผ๋กœ ์ธ์ฆ๋˜์—ˆ์„ ๋•Œ, RequestCache ๋Š” ์›๋ž˜์˜ request๋ฅผ replayํ•œ๋‹ค. RequestCacheAwareFilter ๋Š” ์œ ์ €๊ฐ€ ์ธ์ฆ๋œ ํ›„ ์ €์žฅ๋œ HttpServletRequest ๋ฅผ ์–ป๊ธฐ ์œ„ํ•ด RequestCache ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. ๋ฐ˜๋ฉด์— ExceptionTranslationFilter ๋Š” ์œ ์ €๋ฅผ ๋กœ๊ทธ์ธ endpoint๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ ํ•˜๊ธฐ ์ „์ด๋‚˜ AuthenticationException ์„ ๋ฐœ๊ฒฌํ•œ ํ›„์— HttpServletRequest ๋ฅผ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•ด RequestCache ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

๊ธฐ๋ณธ์ ์œผ๋กœ, HttpSessionRequestCache ๊ฐ€ ์‚ฌ์šฉ๋œ๋‹ค. ์•„๋ž˜ ์ฝ”๋“œ๋Š” RequestCache ๊ตฌํ˜„์ฒด๋ฅผ ์ปค์Šคํ…€ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์„ค๋ช…ํ•œ๋‹ค. ์ €์žฅ๋œ request์— continue ๋ผ๋Š” ์ด๋ฆ„์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ์กด์žฌํ•˜๋Š”์ง€ ์•„๋‹Œ์ง€ HttpSession ์„ ์ฒดํฌํ•œ๋‹ค.

Prevent the Request From Being Saved

์œ ์ €์˜ ์ธ์ฆ๋˜์ง€ ์•Š์€ request๋ฅผ ์„ธ์…˜์— ์ €์žฅํ•˜๊ณ  ์‹ถ์ง€ ์•Š์€ ์—ฌ๋Ÿฌ๊ฐ€์ง€ ์ด์œ ๊ฐ€ ์žˆ์„ ๊ฒƒ์ด๋‹ค. ์ €์žฅ ๋‚ด์šฉ์„ ์œ ์ €์˜ ๋ธŒ๋ผ์šฐ์ €๋กœ ์ €์žฅ์‹œํ‚ค๊ณ  ์‹ถ๊ฑฐ๋‚˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅ์‹œํ‚ค๊ณ  ์‹ถ์„ ์ˆ˜ ์žˆ๋‹ค. ๋˜๋Š” ๋กœ๊ทธ์ธ ํ•˜๊ธฐ ์ „ ์œ ์ €๊ฐ€ ๋ฐฉ๋ฌธํ•˜๋ คํ•œ ํŽ˜์ด์ง€ ๋Œ€์‹ ์— ํ•ญ์ƒ ํ™ˆ ํŽ˜์ด์ง€๋กœ ๋ฆฌ๋‹ค์ด๋ ‰์…˜์„ ์›ํ•˜๋ฉด ์ด ๊ธฐ๋Šฅ์„ ์ฐจ๋‹จํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด๋ฅผ ์œ„ํ•ด์„œ NullRequestCache ๊ตฌํ˜„์ฒด๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

RequestCacheAwareFilter

RequestCacheAwareFilter ๋Š” original request๋ฅผ replay ํ•˜๊ธฐ ์œ„ํ•ด RequestCache ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

Logging

์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ๋Š” ๊ด€๋ จ๋œ ๋ชจ๋“  ์‹œํ๋ฆฌํ‹ฐ ์ด๋ฒคํŠธ์— ๋Œ€ํ•ด DEBUG์™€ TRACE ๋ ˆ๋ฒจ๋กœ ํฌ๊ด„์ ์ธ ๋กœ๊น…์„ ์ œ๊ณตํ•œ๋‹ค. ์ด๋Š” ๋ณด์•ˆ์„ ์œ„ํ•ด ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ๊ฐ€ request๊ฐ€ ๊ฑฐ๋ถ€๋œ ์ด์œ ๋ฅผ response body์— ๋‹ด์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์œ ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ๋งŒ์•ฝ 401 ์—๋Ÿฌ๋‚˜ 403 ์—๋Ÿฌ๋ฅผ ๋งŒ๋‚œ๋‹ค๋ฉด, ์–ด๋–ป๊ฒŒ ์ง„ํ–‰๋˜๊ณ  ์žˆ๋Š”์ง€ ์ดํ•ดํ•˜๋Š” ๊ฒƒ์„ ๋•๋Š” ๋กœ๊ทธ ๋ฉ”์„ธ์ง€๋ฅผ ์ฐพ๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

ํ•œ ์œ ์ €๊ฐ€ POST requst๋ฅผ CSRF ํ† ํฐ ์—†์ด CSRF ํ”„๋กœํ…์…˜์ด ํ™œ์„ฑํ™”๋œ ๋ฆฌ์†Œ์Šค์— POST request๋ฅผ ์‹œ๋„ํ•˜๋Š” ์˜ˆ๋ฅผ ๋“ค์–ด๋ณด์ž. ๋กœ๊ทธ์—†์ด ์‚ฌ์šฉ์ž๋Š” ์™œ request๊ฐ€ ๊ฑฐ์ ˆ๋๋Š”์ง€์— ๋Œ€ํ•œ ์ด์œ ์— ๋Œ€ํ•œ ์„ค๋ช… ์—†์ด 403 ์—๋Ÿฌ๋ฅผ ๋งˆ์ฃผํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋งŒ์•ฝ ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ์— ๋Œ€ํ•ด ๋กœ๊น…์„ ์ ์šฉํ•œ๋‹ค๋ฉด, ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฉ”์„ธ์ง€๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

CSRF ํ† ํฐ์ด ์—†๋‹ค๋Š” ๊ฒƒ์ด ๋ช…ํ™•ํ•ด์ง€๊ณ  request๊ฐ€ ๊ฑฐ์ ˆ๋œ ์ด์œ ๋ฅผ ์•Œ๊ฒŒ๋œ๋‹ค.

์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋ชจ๋“  ์‹œํ๋ฆฌํ‹ฐ ์ด๋ฒคํŠธ์— ๋Œ€ํ•ด ๋กœ๊ทธ๋ฅผ ๋‚จ๊ธฐ๋„๋ก ์„ค์ •ํ•˜๊ธฐ ์œ„ํ•ด, ๋‹ค์Œ ์„ค์ •์„ ์ถ”๊ฐ€ํ•œ๋‹ค.

application.proerties

logback.xml

Last updated