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μ μ§μ μ μΌλ‘ λ±λ‘νλ κ²μ λ§μ μ΄μ μ μ 곡νλ€.
μ€νλ§ μνλ¦¬ν° Servletμ μμμ μ μ 곡νλ€. β trouble shootingμ μ©μ΄
보μ΄μ§ μλ μμ μ μνν μ μλ€. (HttpFireWall λ±)
SecurityFilterChainμ΄ invokeλλ μμ μ κ²°μ νλ λ°μ μ μ°μ±μ μ 곡νλ€.
URLμ κΈ°λ°μΌλ‘ λμνλλ°, RequestMathcer interfaceλ₯Ό μ¬μ©ν¨μΌλ‘μ¨ invocationμ κ²°μ ν μ μλ€.

μ κ·Έλ¦Όμμ FilterChainProxy κ° μ΄λ€ SecurityFilterChainμ΄ μ¬μ©λ μ§ κ²°μ νλ€. λΆν©νλ 첫λ²μ§Έ SecurityFilterChain λ§ μ μ©λλ€. λ§μ½ /api/message/ κ° μμ²λλ€λ©΄, /api/** ν¨ν΄μ SecurityFilterChain0βμ΄ λ§€μΉλλ€. λ°λΌμ λΉλ‘SecurityFilterChainnβλ λ§€μΉλ μ§λΌλ, SecurityFilterChain0β μ΄ μ€νλλ€.
λ§μ½ /essages/ URLμ΄ μμ²λλ€λ©΄ SecurityFilterChain0βκ³Όλ λ§€μΉλμ§ μλλ€. λ°λΌμ FilterChainProxy λ κ°κ°μ SecurityFiterChain μ μλν΄λ³΄λ€κ° κ²°κ΅ SecurityFilterChainnβμ΄ μ μ©λλ€.
SecurityFilterChain0βμ 3κ°μ Filter μΈμ€ν΄μ€λ‘ ꡬμ±λμ΄μκ³ , SecurityFilterChainnβμ 4κ°μ νν° μΈμ€ν΄μ€λ‘ ꡬμ±λμ΄ μλ€. κ°κ°μ SecurityFilterChain μ νΉλ³νκ³ λ
립μ μΌλ‘ ꡬμ±λ μ μλ€. μ¬μ€ SecurityFilterChain μ λ§μ½ μ΄ν리μΌμ΄μ
μ΄ Spring Securityκ° νΉμ requestλ₯Ό 무μνκΈΈ μνλ€λ©΄, Filter μΈμ€ν΄μ€λ₯Ό κ°μ§μ§ μκ² ν μλ μλ€.
Security Filters
Security Filterλ SecurityFilterChain APIμ ν¨κ» FilterChainProxyμ μ½μ λλ€. μ΄ Filterλ€μ μΈμ¦, μΈκ° λ± λ€μν λͺ©μ μΌλ‘ μ¬μ©λ μ μλ€. Filterλ μνλ μμλ‘ μ€νλκΈ° μν΄ νΉμ ν μμλ‘ μ€νλλ€. μλ₯Ό λ€μ΄ μΈμ¦μ μννλ Filterλ μΈκ°λ₯Ό μννλ Filter μ μ μ€νλμ΄μΌ νλ€. Spring Securityμ Filterλ€μ μμλ₯Ό μλ κ²μ μΌλ°μ μΌλ‘ νμν κ²μ μλμ§λ§, μμλ₯Ό μλ κ²μ΄ λμμ΄ λλ λκ° μλ€.
security configurationμ νκ°μ§ μλ₯Ό λ€μ΄λ³΄μ.
μ Configurationμ λ€μμ Filter μμλ₯Ό κ°μ§λ€.
CsrfFilter β
HttpSecurity#csrfCsrfFilterλ CSRF 곡격μ λ§κΈ° μν΄ μ€νλλ€.
UsernamePasswordAuthenticationFilter β
HttpSecurity#formLoginBasicAuthenticationFilter β
HttpSecurity#httpBasicrequestλ₯Ό authenticateνκΈ° μν΄ μ€νλλ€.
AuthorizationFilter β
HttpSecurity#authorizeHttpRequestsAuthorizationFilterλ 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 λ€μλ€κ° μΆκ°ν΄μΌ νλ€.
μν μ½λλ λ€μκ³Ό κ°μ΄ λμνλ€.
request headerλ‘λΆν° tenant idλ₯Ό μ»λλ€.
νμ¬ μ μ κ° tenant idμ μ κ·Ό κΆνμ΄ μλμ§ κ²μ¬νλ€.
μ κ·Ό κΆνμ κ°μ§κ³ μλ€λ©΄ λλ¨Έμ§ νν°λ₯Ό μ€ννλ€.
μ κ·Ό κΆνμ΄ μλ€λ©΄
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 μ λ€λ₯Έ μ»΄ν¬λνΈμμ κ΄κ³λ₯Ό 보μ¬μ€λ€.

ExceptionTranslationFilterκ° μ΄ν리μΌμ΄μ μ λλ¨Έμ§ λΆλΆμ μ€ννκΈ° μν΄FilterChain.doFilter(request, response)λ₯Ό μ€ννλ€.λ§μ½ μ μ κ° μΈμ¦λμ§ μμκ±°λ
AuthenticationExceptionμΈ κ²½μ°, Authenticationμ μμνλ€.SecurityContextHolderκ° μ΄κΈ°νλλ€.
HttpServletRequestλ μΈμ¦μ΄ μ±κ³΅νλ©΄ original requestλ₯Ό replayνλλ° μ¬μ©ν μ μλλ‘ μ μ₯λλ€.AutenticationEntryPointλ ν΄λΌμ΄μΈνΈλ‘λΆν° credentialμ μμ²νκΈ° μν΄ μ¬μ©λλ€. μλ₯Ό λ€μ΄ λ‘κ·ΈμΈ νμ΄μ§λ‘ 리λ€μ΄λ νΈνκ±°λ,WWW-Authenticateν€λλ₯Ό λ³΄λΌ μ μλ€.
AccessDeniedExceptionμΈ κ²½μ°, μ κ·Όμ μ ννλ€.AccessDeniedHandlerκ° μ κ·Όμ μ ννκΈ° μν΄ μ€νλλ€.
λ§μ½ μ΄ν리μΌμ΄μ μ΄
AccessDeniedExceptionμ΄λAuthenticationExceptionμ μΌμΌν€μ§ μλλ€λ©΄,ExceptionTranslationFilterλ μ무κ²λ νμ§ μλλ€.
ExceptionTranslationFilter μ μμ¬μ½λλ λ€μκ³Ό κ°μ΄ λνλΌ μ μλ€.
FilterChain.doFilter(request, response)λ μ΄ν리μΌμ΄μ μ λλ¨Έμ§ λΆλΆμ μ€ννλ κ²κ³Ό κ°λ€. λ§μ½ μ΄ν리μΌμ΄μ μ λλ¨Έμ§ λΆλΆμ΄AuthenticationExceptionλλAccessDeniedExceptionμ λ°μμν¨λ€λ©΄, μ¬κΈ°μ μ²λ¦¬λλ€.λ§μ½ μ μ κ° μΈμ¦λμ§ μμκ±°λ
AuthenticationExceptionμΈ κ²½μ°, Authenticationμ μμνλ€.κ·Έλ μ§ μλ€λ©΄, μ κ·Όμ μ ννλ€.
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