Back-End ์ž‘์—…์‹ค/Spring Framework

[Spring Boot] Spring Security Basic - Spring Security ์ฃผ์š” ์•„ํ‚คํƒ์ณ ์ดํ•ดํ•˜๊ธฐ

์ฃผ๋‹ˆ์“ฐ๐Ÿง‘‍๐Ÿ’ป 2022. 8. 16. 01:10
728x90
๋ฐ˜์‘ํ˜•

์ด ๊ธ€์€ ์ธํ”„๋Ÿฐ -  Spring Boot ๊ธฐ๋ฐ˜์œผ๋กœ ๊ฐœ๋ฐœํ•˜๋Š” Spring Security๋ฅผ ํ•™์Šตํ•˜๋ฉด์„œ ์ •๋ฆฌํ•œ ๋‚ด์šฉ ์ž…๋‹ˆ๋‹ค.

 

 

GIT HUB ์ฃผ์†Œ : https://github.com/junyharang-coding-study/spring-security

 

 

 

 

๐Ÿ—‚ ๋ชฉ์ฐจ

โ— [Spring Boot] Spring Security Basic - ๊ธฐ๋ณธ API ๋ฐ Filter ์ดํ•ดํŽธ 
โ— [Stpring Boot] Spring Security Basic - Spring Security ์ฃผ์š” ์•„ํ‚คํ…์ฒ˜ ์ดํ•ดํŽธ
โ— [Stpring Boot] Spring Security ์‹ค์ „ ํ”„๋กœ์ ํŠธ - ์ธ์ฆ ํ”„๋กœ์„ธ์Šค Form ์ธ์ฆ ๊ตฌํ˜„(1)   
โ— [Stpring Boot] Spring Security ์‹ค์ „ ํ”„๋กœ์ ํŠธ - ์ธ์ฆ ํ”„๋กœ์„ธ์Šค Form ์ธ์ฆ ๊ตฌํ˜„(2)
โ— [Stpring Boot] Spring Security ์‹ค์ „ ํ”„๋กœ์ ํŠธ - ์ธ์ฆ ํ”„๋กœ์„ธ์Šค Ajax ์ธ์ฆ ๊ตฌํ˜„


 

 

 

 

 

๐Ÿš€ Spring Security ์ฃผ์š” ์•„ํ‚คํ…์ฒ˜

    ๐Ÿ”ฝ  ์œ„์ž„ ํ•„ํ„ฐ ๋ฐ ํ•„ํ„ฐ Bean ์ดˆ๊ธฐํ™”

        ๐Ÿ“ฆ DelegationProxyChain

 

1. Servlet Filter๋Š” Spring์—์„œ ์ •์˜๋œ Bean์„ ์ฃผ์ž…ํ•ด์„œ ์‚ฌ์šฉ ๋ถˆ๊ฐ€.
2. ํŠน์ • ์ด๋ฆ„์„ ๊ฐ€์ง„ Spring Bean์„ ์ฐพ์•„ ํ•ด๋‹น Bean์—๊ฒŒ ์š”์ฒญ ์œ„์ž„ ๋ฐฉ์‹์œผ๋กœ ์‚ฌ์šฉ ๊ฐ€๋Šฅ.

   • springSecurityFilterChain ์ด๋ฆ„์œผ๋กœ ์ƒ์„ฑ๋œ Bean์„ ApplicationContext์—์„œ ์ฐพ์•„ ์š”์ฒญ ์œ„์ž„.
   • ์‹ค์ œ ๋ณด์•ˆ์ฒ˜๋ฆฌ๋Š” ํ•˜์ง€ ์•Š์Œ. ์š”์ฒญ์„ ์œ„์ž„ํ•˜๋Š” ์—ญํ• ๋งŒ ์ˆ˜ํ–‰.

 

Servlet Filter๋Š” Servlet Spac์— ์ •์˜๋œ ๊ธฐ์ˆ ๋กœ 2.3 Vesion๋ถ€ํ„ฐ ๋„์ž…์ด ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
์ด ์นœ๊ตฌ๋Š” ์–ด๋–ค ์š”์ฒญ์ด ๋“ค์–ด์™”์„ ๋•Œ, Servlet์ด ์š”์ฒญ์— ๋Œ€ํ•œ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•˜๊ฒŒ ๋˜๋Š”๋ฐ, Servlet์— ๊ฐ€๊ธฐ์ „์— ์ด ์นœ๊ตฌ์—๊ฒŒ ํ•ด๋‹น ์š”์ฒญ์ด ๋จผ์ € ๋“ค์–ด์˜ค๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์–ด๋–ค ์š”์ฒญ์ด ์™”์„ ๋•Œ, ์ฒ˜๋ฆฌํ•˜๊ณ , ์ฒ˜๋ฆฌ๋œ ๋‚ด์šฉ์„ Servlet์—๊ฒŒ ์ „๋‹ฌํ•ด ์ฃผ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

Servlet์—์„œ ์š”์ฒญ ์ฒ˜๋ฆฌ ์ž‘์—…์ด ๋‹ค ๋๋‚˜๊ฒŒ ๋˜๋ฉด ์ตœ์ข…์ ์œผ๋กœ Client์—๊ฒŒ ์‘๋‹ต๊ฐ’์ด ์ „๋‹ฌ๋˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์ด ์‘๋‹ต๊ฐ’์„ ์ „๋‹ฌํ•˜๊ธฐ ์ „์— Servlet Filter๊ฐ€ ๋‹ค์‹œ ์ฒ˜๋ฆฌ๋œ ๋‚ด์šฉ์„ ๋ฐ›์•„ ๋˜ ๋‹ค๋ฅธ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•  ์‹œ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•˜๊ณ , ์‘๋‹ต๊ฐ’์„ ์ตœ์ข…์ ์œผ๋กœ ์ „๋‹ฌํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

Servlet Filter๋Š” Servlet Container์—์„œ ์ƒ์„ฑ์ด ๋˜๊ณ , ์‹คํ–‰์ด ๋˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. 
์ด๋Ÿฌํ•œ ์ด์œ ๋กœ Spring ๊ธฐ์ˆ ์—์„œ ์ฃผ์ž… ๋“ฑ์„ ํ•ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

Spring์—์„œ๋Š” ์œ„์˜ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด Spring Bean์„ ๋งŒ๋“ค๊ณ , Servlet Filter๋ฅผ ๊ตฌํ˜„ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
๊ทธ๋ ‡๊ฒŒ ๋˜๋ฉด Bean์œผ๋กœ ์ƒ์„ฑ๋œ ๊ฐ์ฒด๋Š” Filter Type์˜ ๊ฐ์ฒด๋ฅผ ๊ฐ€์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์ด์šฉ์ž๊ฐ€ ์š”์ฒญ์„ ๋ณด๋‚ด๊ฒŒ ๋˜๋ฉด ํ˜„์žฌ๋Š” Servlet ๊ธฐ๋ฐ˜์œผ๋กœ ์ž‘๋™ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ชจ๋“  ์š”์ฒญ์€ Servlet Filter๋กœ ์ „๋‹ฌ๋˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
์ฆ‰, Spring Bean์ด ๋ฐ”๋กœ ๋ฐ›์ง€ ๋ชปํ•˜๋Š” ๋ฌธ์ œ๊ฐ€ ์ƒ๊ฒจ ๋ฒ„๋ฆฝ๋‹ˆ๋‹ค. WAS์—์„œ Tomcat์ด ์˜ฌ๋ผ๊ฐ€๊ณ , WAS์—์„œ ์‹คํ–‰๋œ Servlet Filter๊ฐ€ ์š”์ฒญ์„ ๋ฐ›๊ฒŒ ๋˜๋Š” ๊ฒƒ ์ž…๋‹ˆ๋‹ค.

Spring Bean์—์„œ ํ•ด๋‹น ์š”์ฒญ์„ ๋ฐ›๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด์„œ DelegatingFilterProxy๋ฅผ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ์ด Class๋Š” Servlet Filter์ธ๋ฐ, ์ด์šฉ์ž ์š”์ฒญ์ด Servlet Filter๋กœ ๋“ค์–ด์˜ค๊ฒŒ ๋˜๋ฉด DelegatingFilterProxy๋Š” ์ด ์š”์ฒญ์„ Spring Bean์—์„œ ๊ด€๋ฆฌํ•˜๋Š” Filter Bean์—๊ฒŒ ์œ„์ž„ํ•˜๋Š” ์—ญํ• ์„ ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

 

        ๐Ÿ“ฆ FilterChainProxy


1. springSecurityFilterChain ์ด๋ฆ„์œผ๋กœ ์ƒ์„ฑ๋˜๋Š” Filter Bean.
2. DelegatingFilterProxy๋กœ ์š”์ฒญ์„ ์œ„์ž„ ๋ฐ›๊ณ , ์‹ค์ œ ๋ณด์•ˆ ์ฒ˜๋ฆฌ.
3. Spring Security ์ดˆ๊ธฐํ™” ์‹œ ์ƒ์„ฑ๋˜๋Š” Filter๋“ค ๊ด€๋ฆฌ ๋ฐ ์ œ์–ด ์—ญํ• .

   • Spring Security๊ฐ€ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ƒ์„ฑํ•˜๋Š” Filter.
   • Config(์„ค์ •) Class์—์„œ API ์ถ”๊ฐ€ ์‹œ ์ƒ์„ฑ๋˜๋Š” Filter.

4. ์ด์šฉ์ž ์š”์ฒญ์„ Filter ์ˆœ์„œ๋Œ€๋กœ ํ˜ธ์ถœํ•˜์—ฌ ์ „๋‹ฌ.
5. ๊ฐœ๋ฐœ์ž ์ •์˜ Filter๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ๊ธฐ์กด Filter ์ „, ํ›„๋กœ ์ถ”๊ฐ€ ๊ฐ€๋Šฅ. (Filter ์ˆœ์„œ๋ฅผ ์ž˜ ์ •์˜ํ•ด์•ผ ํ•จ.)
6. ๋งˆ์ง€๋ง‰ Filter๊นŒ์ง€ ์ธ์ฆ ๋ฐ ์ธ๊ฐ€ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์œผ๋ฉด ๋ณด์•ˆ์  ๋ฌธ์ œ๊ฐ€ ์—†๋‹ค๊ณ  ํŒ๋‹จํ•˜๊ณ , Servlet์— ์ „๋‹ฌ.

 


์ด๋ฒˆ์—๋Š” ์œ„์—์„œ ์–ธ๊ธ‰ํ•œ ๋‘๊ฐœ์˜ Proxy์— ๋Œ€ํ•ด ์ „์ฒด์  ํ๋ฆ„์„ ๊ณต๋ถ€ํ•ด ๋ณผ๊ฒŒ์š”.

Servelet Container์™€ Spring Container๋Š” ์™„์ „ ๋‹ค๋ฅธ ์˜์—ญ์ž…๋‹ˆ๋‹ค.
Servelet Container๋Š” Servelet Spac์„ ๊ตฌํ˜„ํ•˜๋Š” ์˜์—ญ์ด๊ณ , Spring Container๋Š” Spring Container์—์„œ ์ƒ์„ฑ๋˜๋Š” Bean๋“ค์„ ๊ด€๋ฆฌํ•˜๋Š” ์˜์—ญ์ด๋ผ๊ณ  ์ •๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ตœ์ดˆ ์ด์šฉ์ž๊ฐ€ ์ฒ˜์Œ ์š”์ฒญ์„ ํ•˜๊ฒŒ ๋˜๋ฉด Servelet Container๊ฐ€ ๊ฐ€์žฅ ๋จผ์ € ์š”์ฒญ์„ ๋ฐ›๊ฒŒ ๋˜๊ณ , ์š”์ฒญ์— ๋Œ€ํ•ด ๊ฐ๊ฐ์˜ Servlet Filter๋“ค์ด ์ž‘์—…์„ ํ•˜๊ฒŒ ๋˜๊ณ , ์ฒ˜๋ฆฌ ์ž‘์—… ์ค‘ DelegatingFilterProxy๋Š” ์š”์ฒญ์„ ๋ฐ›๊ฒŒ ๋˜๋ฉด ํŠน์ • ์ด๋ฆ„์„ ๊ฐ€์ง„ Bean์„ ์ฐพ์•„ Delegate Request๋ฅผ ๋ณด๋‚ด๊ฒŒ ๋˜๋Š”๋ฐ, ๊ทธ ์ด๋ฆ„์„ ๊ฐ€์ง„ Bean์ด ๋ฐ”๋กœ springSecurityFilterChain์ด์—์š”.

 

๐Ÿ’ก ์ฐธ๊ณ  ์‚ฌํ•ญ

์‹ค์ œ๋กœ๋Š” DelegatingFilterProxy๊ฐ€ Filter๋กœ ๋“ฑ๋ก๋  ๋•Œ, springSecurityFilterChain์ด๋ฆ„์œผ๋กœ ๋“ฑ๋ก์ด ๋ฉ๋‹ˆ๋‹ค.
๋‚ด๋ถ€์ ์œผ๋กœ๋Š” springSecurityFilterChain์ด๋ฆ„์œผ๋กœ ๋“ฑ๋ก๋œ Filter Chain์„ ์ฐพ๊ฒŒ ๋˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

springSecurityFilterChain์ด๋ผ๋Š” ์ด๋ฆ„์„ ๊ฐ€์ง„ Bean์ด ๋ฐ”๋กœ FilterChainProxy์ž…๋‹ˆ๋‹ค.

 

FilterChainProxy๋Š” ๋“ค์–ด์˜จ ์š”์ฒญ์— ๋Œ€ํ•ด์„œ ๊ฐ๊ฐ์˜ Filter๋“ค์„ ํ˜ธ์ถœํ•˜์—ฌ ์ž‘์—… ์ฆ‰, ๋ณด์•ˆ ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๊ฒŒ ๋˜๊ณ , ๋ณด์•ˆ ์ฒ˜๋ฆฌ ์ž‘์—…์ด ๋‹ค ๋˜๊ณ  ๋‚˜๋ฉด Spring MVC, DispatcherServlet์— ์š”์ฒญ์„ ์ „๋‹ฌํ•ด ์ค๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ฒŒ ๋˜๋ฉด DispatcherServlet์ด ์š”์ฒญ์— ๋Œ€ํ•œ ์ถ”๊ฐ€ ์ž‘์—…๋“ค์„ ์ฒ˜๋ฆฌํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 



 

 

 

 

    ๐Ÿ”ฝ  Filter ์ดˆ๊ธฐํ™”์™€ ๋‹ค์ค‘ ๋ณด์•ˆ ์„ค์ •


1. ์„ค์ • Class ๋ณ„๋กœ ๋ณด์•ˆ ๊ธฐ๋Šฅ ๊ฐ๊ฐ ์ž‘๋™.
2. ์„ค์ • Class ๋ณ„๋กœ RequestMatcher ์„ค์ •.

   • http.antMatcher("/admin/**)

3. ์„ค์ • Class ๋ณ„๋กœ Filter ์ƒ์„ฑ.
4. FilterChainProxy๊ฐ€ ๊ฐ๊ฐ Filter ๋ณด์œ .
5. ์š”์ฒญ์— ๋”ฐ๋ผ RequestMatcher์™€ ๋งค์นญ๋˜๋Š” Filter๊ฐ€ ์ž‘๋™ํ•˜๋„๋ก ์ฒ˜๋ฆฌ.

๊ฐœ๋ฐœ์ž๋Š” WebSecurityConfigurerAdapter๋ฅผ ์ด์šฉํ•ด์„œ HttpSecurity๋ฅผ ํ†ตํ•ด ๋ณด์•ˆ ์„ค์ •์„ ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
์ด ๋•Œ, ๋ณด์•ˆ API๋ฅผ ์„ค์ •ํ•˜๊ฒŒ ๋˜๋ฉด Spring Security๊ฐ€ ์ดˆ๊ธฐํ™”๋˜๋ฉด์„œ ๊ฐ๊ฐ์˜ Filter๊ฐ€ ์ƒ์„ฑ๋˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์œ„์˜ ๊ทธ๋ฆผ์—์„œ SecurityConfg 1๊ณผ SecurityConfig 2๋Š” ๊ฐ๊ฐ ๋ณด์•ˆ ๊ธฐ๋Šฅ์ด ๋”ฐ๋กœ ์ž‘๋™ํ•˜๋„๋ก ํ•  ์ˆ˜ ์žˆ์–ด์š”.

๋งŒ์•ฝ SecurityConfig 1์—์„œ RequestMatcher๋ฅผ ํ†ตํ•ด /admin/**์— ๋Œ€ํ•œ ๋ณด์•ˆ ์„ค์ •์„ ํ–ˆ๋‹ค๋ฉด ํ•ด๋‹น ์š”์ฒญ์ด ๋“ค์–ด์™”์„ ๋•Œ, SecurityConfig 1๋งŒ ์ฐธ์กฐํ•˜๊ณ , SecurityConfig 2๋กœ ๋„˜์–ด๊ฐ€์ง„ ์•Š์•„์š”.

์ตœ์ดˆ ๋‹ค์ค‘ ์„ค์ • Class๋ฅผ ๋งŒ๋“ค๊ณ , Spring Security๊ฐ€ ์ดˆ๊ธฐํ™”๊ฐ€ ๋˜๋ฉด SecurityFilterChain Class๊ฐ€ ์žˆ๋Š”๋ฐ, ์ด ๊ฐ์ฒด ์•ˆ์— HttpSecurity๋ฅผ ํ†ตํ•ด ์„ค์ •ํ•œ ์„ค์ •๋œ Filter๊ฐ€ SecurityFilterChain ๊ฐ์ฒด ์•ˆ ๋ณ€์ˆ˜๋กœ ๋‹ด๊ธฐ๊ฒŒ ๋˜๊ณ , http.antMatcher๋ฅผ ํ†ตํ•ด ์ž…๋ ฅํ•œ URI๋Š” RequestMacher๋ผ๋Š” ๊ฐ์ฒด Type์˜ ๋ณ€์ˆ˜์— ๋‹ด๊ธฐ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์œ„์˜ ๋‚ด์šฉ์„ ๋‹ด์€ SecurityFilterChain ๊ฐ์ฒด๊ฐ€ ๊ฐ๊ฐ ์„ค์ •๊ฐ’์— ๋”ฐ๋ผ ๋งŒ๋“ค์–ด์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์ด๋ ‡๊ฒŒ ๊ฐ๊ฐ ์ƒ์„ฑ๋œ ๊ฐ์ฒด๋ฅผ FilterChainProxy๊ฐ€ Filter Type์˜ List ๋ณ€์ˆ˜์— ์ €์žฅ์„ ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

๊ฒฐ๊ตญ ๋‹ค์ค‘ ์„ค์ • Class๋กœ ๋งŒ๋“ค์–ด์ง„ ๋‹ค ์ค‘์˜ ์„ค์ • Filter๋“ค์„ FilterChainProxy๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๊ฒŒ ๋˜๋Š” ๊ฒƒ์ด์—์š”.

๋งŒ์•ฝ ์ด์šฉ์ž๊ฐ€ /admin ์œผ๋กœ ์š”์ฒญ์„ ๋ณด๋‚ด๊ฒŒ ๋˜๋ฉด FilterChainProxy๊ฐ€ ์š”์ฒญ์„ ๋ฐ›๊ฒŒ ๋˜๊ณ , ๊ฐ SecurityConfig ๋‚ด์šฉ ์ค‘ ํ•˜๋‚˜๋ฅผ ์„ ํƒํ•ด์„œ ํ•ด๋‹น ๊ฐ์ฒด Filter์— ์ž‘์—…์„ ์š”์ฒญํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. 

์œ„์˜ ๊ทธ๋ฆผ์—์„œ๋Š” /admin URI์— ๋Œ€ํ•œ RequestMacher๊ฐ€ SecurityConfig 1์— ์žˆ์–ด์š”.
๊ทธ๋ ‡๋‹ค๋ฉด FilterChainProxy๋Š” SecurityConfig 1์— SecurityFilterChain ๊ฐ์ฒด๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” Filters ๋ณ€์ˆ˜๋“ค์„ ๊ฐ€์ง€๊ณ  ์˜จ ๋’ค ์ธ์ฆ / ์ธ๊ฐ€ ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๊ฒŒ ๋˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค.

728x90


์œ„์˜ ๊ทธ๋ฆผ์„ ๋ณด๋ฉด์„œ ๊ณต๋ถ€๋ฅผ ํ•ด ๋ณผ๊ฒŒ์š”.

์ด์šฉ์ž๊ฐ€ ์ตœ์ดˆ GET ๋ฐฉ์‹์œผ๋กœ /admin URI์— ์ ‘๊ทผ ์š”์ฒญ์„ ๋ณด๋ƒˆ์–ด์š”.

๊ทธ๋Ÿฌ๋ฉด FilterChainProxy๊ฐ€ ํ•ด๋‹น ์š”์ฒญ์„ ๋ฐ›๊ฒŒ ๋˜๊ณ , ํ•ด๋‹น ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•  Filter๋ฅผ ์„ ํƒํ•ด์•ผ ํ•˜๋Š”๋ฐ, ์š”์ฒญ URI์™€ Magching์ด ๋˜๋Š” ์ฆ‰, matches์—์„œ True๊ฐ’์ด ๋‚˜์˜ค๋Š” Config Filter๋ฅผ ๊ฐ€์ ธ์™€์•ผ ํ•ด์š”.

์ด ๋•Œ, FilterChainProxy๊ฐ€ ์ €์žฅํ•˜๊ณ  ์žˆ๋Š” ๊ฐ๊ฐ์˜ SecurityFilterChain ๊ฐ์ฒด๋“ค ์ค‘ RequestMatcher ๋‚ด์— Matching์ด ๋˜๋Š” ๊ฒƒ์„ ์ฐพ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

(SecurityConfig 2์˜ RequestMacher๋Š” anyRequest ์ž…๋‹ˆ๋‹ค.)

๊ทธ๋ ‡๊ฒŒ ๋˜๋ฉด SecurityConfig 1 ๋‚ด์— SecurityFilterChain์ด ๊ฐ€์ง€๊ณ  ์žˆ๋Š” RequestMacher์™€ ๋งค์นญ์ด ๋ฉ๋‹ˆ๋‹ค.
๊ทธ๋Ÿผ ํ•ด๋‹น ๊ฐ์ฒด ์•ˆ์— Filter๊ฐ€ ๋™์ž‘ํ•˜๋„๋ก ์„ ํƒํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ ๋’ค ์ธ์ฆ / ์ธ๊ฐ€ ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๊ฒŒ ๋˜๋Š” ๊ฒƒ์ด์—์š”.

/admin์ด ์•„๋‹Œ ๋‹ค๋ฅธ URI๋กœ ์˜ค๋Š” ์š”์ฒญ์— ๋Œ€ํ•ด์„œ๋Š” SecurityConfig 2 ๋‚ด์šฉ์„ ๊ฐ€์ ธ์˜ค๊ณ , ๋™์ž‘ํ•˜๊ฒŒ ๋  ๊ฒƒ์ด์—์š”.




์ด ์ „์— ์ž‘์„ฑํ–ˆ๋˜ Code์™€ ๋‹ค๋ฅธ ์ƒˆ๋กœ์šด Config Code๋ฅผ ์ž‘์„ฑํ–ˆ์–ด์š”.

์ด๋ ‡๊ฒŒ ํ•˜๊ณ , Server๋ฅผ ๊ธฐ๋™ํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ๊ฑฐ์—์š”.

๋ฐ˜์‘ํ˜•
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2022-08-16 16:22:00.129 ERROR 2702 --- [           main] o.s.boot.SpringApplication               : Application run failed

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration': Injection of autowired dependencies failed; nested exception is java.lang.IllegalStateException: @Order on WebSecurityConfigurers must be unique. Order of 100 was already used on com.junyharang.spring.security.config.SecurityMultiConfig$$EnhancerBySpringCGLIB$$941cc1dd@21c815e4, so it cannot be used on com.junyharang.spring.security.config.SecurityMultiConfig2$$EnhancerBySpringCGLIB$$21af67c3@7342e05d too.
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:405) ~[spring-beans-5.3.20.jar:5.3.20]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1431) ~[spring-beans-5.3.20.jar:5.3.20]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:619) ~[spring-beans-5.3.20.jar:5.3.20]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.20.jar:5.3.20]
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.20.jar:5.3.20]
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.20.jar:5.3.20]
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.20.jar:5.3.20]
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.20.jar:5.3.20]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:953) ~[spring-beans-5.3.20.jar:5.3.20]
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) ~[spring-context-5.3.20.jar:5.3.20]
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) ~[spring-context-5.3.20.jar:5.3.20]
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:147) ~[spring-boot-2.7.0.jar:2.7.0]
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:734) ~[spring-boot-2.7.0.jar:2.7.0]
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408) ~[spring-boot-2.7.0.jar:2.7.0]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:308) ~[spring-boot-2.7.0.jar:2.7.0]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306) ~[spring-boot-2.7.0.jar:2.7.0]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1295) ~[spring-boot-2.7.0.jar:2.7.0]
	at com.junyharang.spring.security.JunyharangSpringSecutiryApplication.main(JunyharangSpringSecutiryApplication.java:10) ~[classes/:na]
Caused by: java.lang.IllegalStateException: @Order on WebSecurityConfigurers must be unique. Order of 100 was already used on com.junyharang.spring.security.config.SecurityMultiConfig$$EnhancerBySpringCGLIB$$941cc1dd@21c815e4, so it cannot be used on com.junyharang.spring.security.config.SecurityMultiConfig2$$EnhancerBySpringCGLIB$$21af67c3@7342e05d too.
	at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration.setFilterChainProxySecurityConfigurer(WebSecurityConfiguration.java:165) ~[spring-security-config-5.7.1.jar:5.7.1]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
	at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:724) ~[spring-beans-5.3.20.jar:5.3.20]
	at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:119) ~[spring-beans-5.3.20.jar:5.3.20]
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399) ~[spring-beans-5.3.20.jar:5.3.20]
	... 17 common frames omitted

๋Œ€์ƒ VM์—์„œ ์—ฐ๊ฒฐ ํ•ด์ œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ฃผ์†Œ: '127.0.0.1:50961', ์ „์†ก: '์†Œ์ผ“'

์ข…๋ฃŒ ์ฝ”๋“œ 1(์œผ)๋กœ ์™„๋ฃŒ๋œ ํ”„๋กœ์„ธ์Šค


์ด๊ฒƒ์€ WebSecurityConfigurers์— uniqueํ•œ Annotation @order๊ฐ€ ์žˆ๋Š”๋ฐ, Spring Security Config๋ฅผ N๊ฐœ ๋งŒ๋“ค ๊ฒฝ์šฐ ์„ค์ •์— ๋”ฐ๋ผ์„œ ์ˆœ์„œ๋ฅผ ์ •์˜ํ•ด ์ค˜์•ผ ํ•ด์š”.

๊ทธ๋ž˜์„œ ๊ทธ ์ˆœ์„œ๋ฅผ ์ •์˜ํ•˜๊ธฐ ์œ„ํ•œ Annotation @order๋ฅผ ์ด์šฉํ•ด์„œ ์ˆœ์„œ๋ฅผ ์ •์˜ํ•ด ๋‹ฌ๋ผ๋Š” ๊ฑฐ์—์š”.


์ด๋ ‡๊ฒŒ ์œ„์™€ ๊ฐ™์ด ์ˆ˜์ •์„ ํ•ด์ฃผ๊ณ  ๋‹ค์‹œ ๊ธฐ๋™์„ ํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ์ •์ƒ ๊ธฐ๋™์ด ๋ฉ๋‹ˆ๋‹ค.




 

 

 

    ๐Ÿ”ฝ  ์ธ์ฆ ๊ฐœ๋… ์ดํ•ด

        ๐Ÿ“ฆ Authentication

Authentication์ด๋ž€? ์ธ์ฆ ์ฆ‰, ์ด์šฉ์ž๊ฐ€ ๋ˆ„๊ตฌ์ธ์ง€ ์ฆ๋ช…ํ•˜๋Š” ๊ฒƒ์ด์—์š”.

1. ์ด์šฉ์ž์˜ ์ธ์ฆ ์ •๋ณด๋ฅผ ์ €์žฅํ•˜๋Š” Token ๊ฐœ๋….
2. ์ธ์ฆ ์‹œ ID, Password๋ฅผ ๋‹ด๊ณ  ์ธ์ฆ ๊ฒ€์ฆ์„ ์œ„ํ•ด ๊ฐ Class ๋งˆ๋‹ค ์ „๋‹ฌ ๋˜์–ด ์‚ฌ์šฉ.
3. ์ธ์ฆ ๋’ค ์ตœ์ข… ์ธ์ฆ ๊ฒฐ๊ณผ (USER ๊ฐ์ฒด, ๊ถŒํ•œ ์ •๋ณด)๋ฅผ ๋‹ด๊ณ  SecurityContext์— ์ €์žฅ๋˜์–ด ์ „์—ญ์ ์œผ๋กœ ์ฐธ์กฐ ๊ฐ€๋Šฅ.

   • Authentication authentication = SecurityContextHolder.getContext().getAuthentication()

4. ๊ตฌ์กฐ (Authentication์€ Interface).

   • principal(Spring Secutiry๊ฐ€ ์•„๋‹Œ JAVA๊ฐ€ ์ง€์›) : ์ด์šฉ์ž ID ํ˜น์€ USER ๊ฐ์ฒด ์ €์žฅ.
   • credntials : ์ด์šฉ์ž Password.
   • authorities : ์ธ์ฆ๋œ ์ด์šฉ์ž ๊ถŒํ•œ ๋ชฉ๋ก.
   • details : ์ธ์ฆ ๋ถ€๊ฐ€ ์ •๋ณด.
   • Authenticated : ์ธ์ฆ ์—ฌ๋ถ€.

 


์ตœ์ดˆ ์ด์šฉ์ž๊ฐ€ Login์„ ์‹œ๋„ํ•  ๋•Œ, ID์™€ Password๋ฅผ Server์— ๋„˜๊ฒจ์ฃผ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
๊ทธ๋Ÿฌ๋ฉด UsernamePasswordAuthenticationFilter(์ธ์ฆ Filter)๊ฐ€ ID(Username)์™€ Password ์ •๋ณด๋ฅผ ์ถ”์ถœํ•œ ๋’ค Authentication Type ๊ฐ์ฒด๋ฅผ ํ•˜๋‚˜ ๋งŒ๋“ค๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.


์ด ๋•Œ, princlpal์—๋Š” ์ด์šฉ์ž ID๋ฅผ ๋„ฃ๊ณ , credentials์—๋Š” ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ๋‹ด๊ณ , ์ „๋‹ฌ๋˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

AntuehticationManager๊ฐ€ ์ธ์ฆ ๊ฐ์ฒด๋ฅผ ๊ฐ€์ง€๊ณ , ์ธ์ฆ ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๊ฒŒ ๋˜๊ณ , ์ธ์ฆ์ด ์‹คํŒจํ•˜๊ฒŒ ๋˜๋ฉด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๊ฒŒ ๋˜๊ณ , ์‹คํŒจ์— ๋Œ€ํ•œ ํ›„์† ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๊ฒŒ ๋˜๊ณ , ์„ฑ๊ณตํ•˜๊ฒŒ ๋˜๋ฉด Authentication Type์— ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ฒŒ ๋˜๋Š”๋ฐ, princlpal์—๋Š” ์ด์šฉ์ž ID๋ฅผ ๋„ฃ๊ณ , credentials์—๋Š” ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ๋‹ด๋Š”๋ฐ, ๋ณด์•ˆ์ƒ ๋น„์–ด๋‘๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค.
Authorities์—๋Š” ๊ถŒํ•œ ์ •๋ณด ๋ชฉ๋ก์„ ๋‹ด๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๊ณ  ๋‚œ ๋’ค SecurityContextHolder ์•ˆ์— SecurityContext ๊ฐ์ฒด์— ํ•ด๋‹น ์ธ์ฆ ๊ฐ์ฒด(Authentication)์„ ๋‹ด๊ฒŒ ๋˜๊ณ , ์ด ์ธ์ฆ ๊ฐ์ฒด๋ฅผ ์ „์—ญ์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด ์ค๋‹ˆ๋‹ค.

 

 

 

    ๐Ÿ”ฝ  ์ธ์ฆ ์ €์žฅ์†Œ


์ตœ์ดˆ ์ด์šฉ์ž๊ฐ€ Login์„ ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค.

Server๊ฐ€ Login ์š”์ฒญ์„ ๋ฐ›๊ฒŒ ๋˜๋ฉด Server๋Š” ํ•ด๋‹น ์ด์šฉ์ž์— ๋Œ€ํ•œ Thread ํ•˜๋‚˜๋ฅผ ์ƒ์„ฑํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
์ด ๋•Œ, ThreadLocal์ด๋ผ๋Š” Thread ์ „์—ญ ์ €์žฅ์†Œ๊ฐ€ Thread ๋งˆ๋‹ค ํ• ๋‹น์ด ๋ฉ๋‹ˆ๋‹ค.

ํ•ด๋‹น Thrad๋Š” ์ธ์ฆ์„ ์ฒ˜๋ฆฌํ•˜๊ฒŒ ๋˜๋Š”๋ฐ, ์ด ๋•Œ, ์ธ์ฆ Filter์ธ UsernamePasswordAuthenticationFilter๊ฐ€ ๋™์ž‘ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์ตœ์ดˆ Authentication ๊ฐ์ฒด๋ฅผ ๋งŒ๋“œ๋Š”๋ฐ, ID์™€ Password๋งŒ ๋‹ด๊ธฐ ์œ„ํ•ด principal์—๋Š” ID ๊ฐ’์„ Credentials์—๋Š” Password๊ฐ’์„ ๋‹ด๊ฒŒ ๋˜๊ณ , ๋‚˜๋จธ์ง€๋Š” ๋‹ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ ๋’ค ์ธ์ฆ์„ ์‹œ๋„ํ•ด์„œ ์ธ์ฆ์ด ์‹คํŒจํ•˜๊ฒŒ ๋˜๋ฉด SecurityContextHolder.clearContext()๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ SecurityContext๊ฐ’์„ Null๋กœ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ์ž‘์—…์„ ํ•˜๊ณ , ์ธ์ฆ์ด ์„ฑ๊ณตํ–ˆ๋‹ค๋ฉด UsernamePasswordAuthenticationFilter๊ฐ€ SecurityContextHolder์•ˆ์— SecurityContext ๊ฐ์ฒด ์•ˆ์— ์ตœ์ข… ์ธ์ฆ ์„ฑ๊ณตํ•œ ์ธ์ฆ ๊ฐ์ฒด๋ฅผ ๋‹ด๋Š” ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์ด ๋•Œ, ์ด์šฉ์ž์—๊ฒŒ ํ• ๋‹น๋œ ๊ถŒํ•œ์ด ๋‹ด๊ธฐ๊ฒŒ ๋˜๊ณ , ์ธ์ฆ ์—ฌ๋ถ€๊ฐ€ True๋กœ ๋ฐ”๋€Œ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์ข€ ๋” ์„ธ๋ถ€์ ์œผ๋กœ ์ด์•ผ๊ธฐ ํ•˜์ž๋ฉด SecurityContextHolder๋Š” ThradLocal ๊ฐ์ฒด๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๊ฒŒ ๋˜๊ณ , ThradLocal ๊ฐ์ฒด๊ฐ€ SecurityContext ๊ฐ์ฒด๋ฅผ ๋‹ด๊ณ  ์žˆ๋‹ค๊ณ  ๋งํ•˜๋Š”๊ฒŒ ๋” ์ •ํ™•ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ ๋’ค ์ตœ์ข…์ ์œผ๋กœ SecurityContext ๊ฐ์ฒด๊ฐ€ HttpSession ๊ฐ์ฒด์— ์ €์žฅ์ด ๋ฉ๋‹ˆ๋‹ค. ์ด ๋•Œ, ์ด๋ฆ„์€ SPRING_SECURITY_CONTEXT๋กœ ์ €์žฅ๋˜์š”.

 

 

        ๐Ÿ“ฆ SecurityContextHolder

1. SecurityContext ๊ฐ์ฒด ์ €์žฅ ๋ฐฉ์‹.

   • MODE_THREADLOCAL : Thread ๋‹น SecurityContext ๊ฐ์ฒด ํ• ๋‹น (Default Value).
   • MODE_INHERITABLETHREADLOCAL : Main Thread์™€ ์ž์‹ Thread์— ๊ด€ํ•˜์—ฌ ๋™์ผ SecurityContext ์œ ์ง€.
   • MODE_GLOBAL : ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์—์„œ ๋‹จ ํ•˜๋‚˜์˜ SecurityContext ์ €์žฅ.

2. SecurityContextHolder.clearContext() : SecurityContext ๊ธฐ์กด ์ •๋ณด ์ดˆ๊ธฐํ™”.

 

 

        ๐Ÿ“ฆ SecurityContext

1. Authentication ๊ฐ์ฒด๊ฐ€ ์ €์žฅ๋˜๋Š” ๋ณด๊ด€์†Œ. ํ•„์š” ์‹œ ์–ธ์ œ๋“ ์ง€ Authentication ๊ฐ์ฒด๋ฅผ ๊บผ๋‚ด ์“ธ ์ˆ˜ ์žˆ๋„๋ก ์ œ๊ณต๋˜๋Š”           
    Class.

2. ThreadLocal์— ์ €์žฅ๋˜์–ด ์•„๋ฌด ๊ณณ์—์„œ๋‚˜ ์ฐธ์กฐ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋„๋ก ์„ค๊ณ„.

   • Thread๋Š” Thread๋งˆ๋‹ค ๊ณ ์œ ํ•˜๊ฒŒ ํ• ๋‹น๋œ ์ €์žฅ์†Œ๊ฐ€ ์žˆ๋Š”๋ฐ, ๊ทธ ์ €์žฅ์†Œ๋ฅผ Thread Local์ด๋ผ๊ณ  ํ•œ๋‹ค.
   • ํ•ด๋‹น ์ €์žฅ์†Œ์—๋Š” ์ฃผ์ธ Thread๋งŒ ์ ‘๊ทผ ๋ฐ Data ์ €์žฅ์ด ๊ฐ€๋Šฅ.
   • Set, Get Method ๋“ฑ ํ†ตํ•ด Data Handling ๊ฐ€๋Šฅ.
   • Data๋ฅผ Set์œผ๋กœ ์ €์žฅํ•œ ๋’ค, Get์œผ๋กœ ์ฐธ์กฐ๊ฐ€ ๊ฐ€๋Šฅํ•œ๋ฐ, ์ €์žฅ ์ด ํ›„ Get์œผ๋กœ ์ฐธ์กฐ๋ฅผ ํ•  ๋•Œ, ์žฅ์†Œ์— ๊ตฌ์•  ๋ฐ›์ง€ ์•Š๋Š”๋‹ค.
      ์˜ˆ๋ฅผ ๋“ค์–ด A๋ผ๋Š” Method์•ˆ์—์„œ Thread Local์ด Set์œผ๋กœ ์ €์žฅ์„ ํ•˜๊ณ , ๋‹ค๋ฅธ ์žฅ์†Œ์ธ B Method์—์„œ Get์„ ํ†ตํ•ด
      A Method์—์„œ ์ €์žฅํ•œ Data๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค.

3. ์ธ์ฆ ์™„๋ฃŒ ์‹œ HttpSession์— ์ €์žฅ๋˜์–ด Application ์ „๋ฐ˜์— ๊ฑธ์ณ ์ „์—ญ ์ฐธ์กฐ ๊ฐ€๋Šฅ.

 

 

 

 

    ๐Ÿ”ฝ  ์ธ์ฆ ์ €์žฅ์†Œ Filter

        ๐Ÿ“ฆ SecurityContextPersistenceFilter

1. SecurityContext ๊ฐ์ฒด์˜ ์ƒ์„ฑ, ์ €์žฅ, ์กฐํšŒ

   • ์ต๋ช… ์ด์šฉ์ž
      - ์ƒˆ๋กœ์šด SecurityContext ๊ฐ์ฒด ์ƒ์„ฑ ๋’ค SecurityContextHolder์— ์ €์žฅ.
      - AnonymousAuthenticationFilter์—์„œ AnnonymousAuthenticationToken(์ต๋ช… ์ด์šฉ์ž์šฉ ์ธ์ฆ ๊ฐ์ฒด) 
         ๊ฐ์ฒด๋ฅผ SecurityContext์— ์ €์žฅ.

   • ์ธ์ฆ ์‹œ
      - ์ƒˆ๋กœ์šด SecurityContext ๊ฐ์ฒด ์ƒ์„ฑ ๋’ค SecurityContextHolder์— ์ €์žฅ.
      - UsernamePasswordAuthenticationFilter ์—์„œ ์ธ์ฆ ์„ฑ๊ณต ๋’ค SecurityContext์—
         UsernamePasswordAuthenticationToken ๊ฐ์ฒด๋ฅผ SecurityContext์— ์ €์žฅ.
      - ์ธ์ฆ์ด ์ตœ์ข… ์™„๋ฃŒ ๋˜๋ฉด ์‘๋‹ต ํ•˜๋Š” ์‹œ์ ์— Session์— SecurityContext ์ €์žฅ.

   • ์ธ์ฆ ๋’ค
      - Session์—์„œ SecurityContext ๊ฐ์ฒด๋ฅผ ๊บผ๋‚ด SecurityContextHolder์—์„œ ์ €์žฅ.
      - SecurityContext ์•ˆ Authentication ๊ฐ์ฒด๊ฐ€ ์กด์žฌํ•˜๋ฉด ๊ณ„์† ์ธ์ฆ ์œ ์ง€.

   • ์ตœ์ข… ์‘๋‹ต ์‹œ ๊ณตํ†ต
     - SecurityContextHolder.clearContext()




์ตœ์ดˆ ์ด์šฉ์ž๊ฐ€ ์ธ์ฆ์„ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค.

SecurityContextPersistenceFilter๋Š”  ๋งค ์š”์ฒญ๋งˆ๋‹ค ํ•ด๋‹น ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
์ธ์ฆ์„ ์š”์ฒญํ•˜๋Š” ์ด์šฉ์ž, ์ธ์ฆ์„ ๋ฐ›์€ ์ด์šฉ์ž, ์ต๋ช… ์ด์šฉ์ž ๋“ฑ ๋ชจ๋‘  SecurityContextPersistenceFilter๊ฐ€ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

SecurityContextPersistenceFilter ์•ˆ์—๋Š” HttpSecurityContextRepository Class๊ฐ€ ์žˆ๋Š”๋ฐ, ์‹ค์ œ HttpSecurityContextRepository๊ฐ€ SecurityContext ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ , ์กฐํšŒ ๋“ฑ์„ ํ•˜๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.

์ด์ œ ์ด์šฉ์ž๊ฐ€ ์ธ์ฆ์„ ๋ฐ›์•˜๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ํŒ๋‹จํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
์ด ๋•Œ, Session์— SecurityContext๊ฐ€ ์žˆ๋Š”์ง€๋ฅผ ํ™•์ธํ•˜๊ฒŒ ๋˜๋Š”๋ฐ, ๋‹น์—ฐํžˆ ์ธ์ฆ ์ „์ด๊ฑฐ๋‚˜, ์ต๋ช… ์ด์šฉ์ž๊ฐ€ ์ ‘๊ทผํ•˜๊ฒŒ ๋˜๋ฉด
SecurityContext๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์„๊ฑฐ์—์š”.

๊ทธ๋ž˜์„œ ์ธ์ฆ์„ ๋ฐ›๊ธฐ ์ „์ด๊ณ , ์ธ์ฆ์„ ์š”์ฒญํ•˜๊ณ  ์žˆ๋‹ค๋ฉด ์ƒˆ๋กœ์šด SecurityContext๋ฅผ ์ƒ์„ฑํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
์ด๋Š” ์ต๋ช… ์ด์šฉ์ž, ์ธ์ฆ์„ ๋ฐ›๊ธฐ ์‹œ์ ์— ์ด์šฉ์ž๋“  ๋™์ผํ•ด์š”.
์ด ๋•Œ๋Š” Authentication (์ธ์ฆ ๊ฐ์ฒด)๊ฐ€ Null์ธ ์ƒํƒœ์—์š”.

์š”์ฒญ์€ ๊ทธ ๋‹ค์Œ Filter๋กœ ์ด๋™(chain.doFilter)๋˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

AuthFilter ์˜ˆ๋ฅผ ๋“ค์–ด Form ์ธ์ฆ์˜ ๊ฒฝ์šฐ UsernamePasswordAuthenticationFilter๊ฐ€ ๋  ๊ฒƒ์ธ๋ฐ, ํ•ด๋‹น ์ธ์ฆ Filter๊ฐ€ ์ธ์ฆ์„ ์ฒ˜๋ฆฌํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์ธ์ฆ์ด ์™„๋ฃŒ๊ฐ€ ๋˜๋ฉด ํ•ด๋‹น ์ธ์ฆ Filter๊ฐ€ SecurityContextHolder ์•ˆ์—์„œ SecurityContext ๊ฐ์ฒด ์•ˆ์—  ์ธ์ฆ์— ์„ฑ๊ณตํ•œ ๊ฒฐ๊ณผ๋ฌผ์ธ Authentication(์ธ์ฆ ๊ฐ์ฒด)๋ฅผ ์ €์žฅํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

๊ฒฐ๊ตญ SecurityContextPersistenceFilter๋Š” ์ธ์ฆ ์š”์ฒญ์ด ์™”์„ ๋•Œ,SecurityContext ๊ฐ์ฒด ์ƒ์„ฑ๋งŒ ๋‹ด๋‹นํ•˜๊ณ , ๋‹ค์Œ Filter๋กœ ๋„˜๊ธฐ๋Š” ์ž‘์—…๋งŒ ํ•˜๋Š” ๊ฒƒ์ด์—์š”.

์š”์ฒญ์€ ๊ทธ ๋‹ค์Œ Filter๋กœ ์ด๋™(chain.doFilter)๋˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์ตœ์ข…์ ์œผ๋กœ ์ธ์ฆ ๊ฒฐ๊ณผ๋ฅผ Client์—๊ฒŒ ์‘๋‹ตํ•˜๋ ค ํ•  ๋•Œ, Session ์•ˆ์— SecurityContext ๊ฐ์ฒด๋ฅผ ์ €์žฅํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
์ด ์ž‘์—…์€ ์ธ์ฆ Filter๊ฐ€ ์•„๋‹Œ SecurityContextPersistenceFilter๊ฐ€ ์ž‘์—…์„ ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ ๋‹ค์Œ SecurityContextHolder์•ˆ์— SecurityContext ๊ฐ์ฒด๋ฅผ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.
์ œ๊ฑฐํ•˜๋Š” ์ด์œ ๋Š” ๋งค ์š”์ฒญ์‹œ ๋งˆ๋‹ค SecurityContextPersistenceFilter๋Š” ์ƒˆ๋กœ์šด SecurityContext ๊ฐ์ฒด๋ฅผ SecurityContextHolder์•ˆ์— ์ƒ์„ฑํ•˜๊ฒŒ ๋ ํ…๋ฐ, ์ด๋ฏธ Session์— ํ•ด๋‹น ๊ฐ์ฒด๊ฐ€ ์ €์žฅ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ™์€ ๊ฐ’์„ ๊ณ„์† ๋ˆ„์ ํ•ด์„œ ๊ฐ€์ง€๊ณ  ์žˆ์„ ํ•„์š”๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์ด์—์š”.

๊ทธ๋Ÿฐ ๋‹ค์Œ ์ตœ์ข…์ ์œผ๋กœ Client์—๊ฒŒ ์‘๋‹ต์„ ๋ณด๋‚ด๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.


์ธ์ฆ์ด ์„ฑ๊ณตํ•œ ๋’ค ์ด์šฉ์ž๋Š” ์–ด๋–ค ์ž์›์— ์ ‘๊ทผ ์š”์ฒญ์„ ๋ณด๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ๋•Œ์—๋„ ์—ญ์‹œ SecurityContextPersistenceFilter๊ฐ€ ์š”์ฒญ์„ ๋ฐ›๊ฒŒ ๋˜๊ณ , HttpSecurityContextRepository๊ฐ€ ์š”์ฒญ์„ ์‹ค์ œ๋กœ ์ฒ˜๋ฆฌํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์ด ๋•Œ์—๋Š” ์ธ์ฆ์„ ์„ฑ๊ณตํ•œ ๋’ค์ด๊ธฐ ๋•Œ๋ฌธ์— Session์— SecurityContext ๊ฐ์ฒด๊ฐ€ ์กด์žฌํ•  ๊ฑฐ์—์š”.
์™œ๋ƒํ•˜๋ฉด ์ธ์ฆ ์‹œ์ ์— Session์— SecurityContext๋ฅผ ์ €์žฅํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ด์—์š”.

์ด์ œ๋Š” Session์— ์ €์žฅ๋œ SecurityContext ๊ฐ์ฒด๋ฅผ ๊บผ๋‚ด์„œ SecurityContextHolder์— SecurityContext ๊ฐ์ฒด ์•ˆ์— Authentication(์ธ์ฆ ๊ฐ์ฒด)๋ฅผ ์ €์žฅ ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ ๋’ค ๊ทธ ๋‹ค์Œ Filter๋กœ ์ด๋™(chain.doFilter)๋˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.




์กฐ๊ธˆ ๋” ๋‚ด์šฉ์„ ์š”์•ฝํ•ด ๋ณด์ž๋ฉด SecurityContextPersistenceFilter๋Š” ์ธ์ฆ ๋ฐ›๊ธฐ ์ „์ด๋ผ๋ฉด ์ƒˆ๋กœ์šด SecurityContext๋ฅผ ์ƒ์„ฑํ•˜๊ฒŒ ๋˜๋Š”๋ฐ, ๊ตฌ์กฐ๋ฅผ ๋ณด๋ฉด SecurityContextHolder ์•ˆ์— ThreadLocal์ด ์žˆ๊ณ , ๊ทธ ์•ˆ์— SecurityContext๋ฅผ ์ƒ์„ฑํ•˜๊ฒŒ ๋˜๋Š”๋ฐ, ์ธ์ฆ์„ ๋ฐ›๊ธฐ ์ „์ด๊ธฐ ๋•Œ๋ฌธ์— Null์ธ ์ƒํƒœ๋กœ ๋งŒ๋“ค๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์ธ์ฆ์„ ๋ฐ›์€ ๋’ค๋ผ๋ฉด ์ƒˆ๋กœ์šด SecurityContext๋ฅผ ์ƒ์„ฑํ•˜๊ฒŒ ๋˜๋Š”๋ฐ, ๊ตฌ์กฐ๋ฅผ ๋ณด๋ฉด SecurityContextHolder ์•ˆ์— ThreadLocal์ด ์žˆ๊ณ , ๊ทธ ์•ˆ์— SecurityContext๋ฅผ ์ƒ์„ฑํ•˜๊ฒŒ ๋˜๋Š”๋ฐ, ์ธ์ฆ ์„ฑ๊ณตํ•œ Authentication (์ธ์ฆ ๊ฐ์ฒด)๋ฅผ ์ €์žฅํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์ธ์ฆ์„ ๋ฐ›์€ ๋’ค ์ž์› ์ ‘๊ทผ๊ณผ ๊ฐ™์€ ์š”์ฒญ์ด ์˜ค๊ฒŒ ๋˜๋ฉด Session์— SecurityContext ๊ฐ์ฒด๋ฅผ ๊บผ๋‚ด SecurityContextHolder ์•ˆ์— ๋‹ด๋Š” ๋ฐฉ์‹์œผ๋กœ ์ฒ˜๋ฆฌ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.






    ๐Ÿ”ฝ  ์ธ์ฆ ํ๋ฆ„ ์ดํ•ด

        ๐Ÿ“ฆ Authentication Flow

 


์ด์šฉ์ž๊ฐ€ Form ์ธ์ฆ ๋ฐฉ์‹์˜ ์ธ์ฆ ์š”์ฒญ์„ ๋ณด๋ƒˆ์„ ๋•Œ, ์–ด๋–ค์ผ์ด ๋ฒŒ์–ด์ง€๋Š”์ง€ ์•Œ์•„๋ณผ๊ฒŒ์š”.

UsernamePasswordAuthenticationFilter(Form ์ธ์ฆ ์ฒ˜๋ฆฌ Filter)๋Š” ์ตœ์ดˆ ์ด ์š”์ฒญ์„ ๋ฐ›๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
์ด ์นœ๊ตฌ๋Š” ๊ฐ€์žฅ ๋จผ์ € ID์™€ Password๋ฅผ ๋ฐ›์•„ ์ธ์ฆ ๊ฐ์ฒด Authentication์„ ๋งŒ๋“ค๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

UsernamePasswordAuthenticationFilter๋Š” AuthenticationManager์—๊ฒŒ ํ•ด๋‹น ๊ฐ์ฒด๋ฅผ ์ „๋‹ฌํ•˜๋ฉด์„œ ์ธ์ฆ ์ฒ˜๋ฆฌ๋ฅผ ์ „๋‹ฌํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์—ฌ๊ธฐ๊นŒ์ง€๊ฐ€ Filter๊ฐ€ ์ธ์ฆ ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๋Š” ์ฒซ๋ฒˆ์งธ ๋‹จ๊ณ„์ž…๋‹ˆ๋‹ค.

AuthenticationManager๋Š” ์ธ์ฆ์˜ ์ „๋ฐ˜์ ์ธ ๊ด€๋ฆฌ๋Š” ํ•˜์ง€๋งŒ, ์‹ค์ œ ์ธ์ฆ ์—ญํ• ์€ ํ•˜์ง€ ์•Š๊ณ , ์ ์ ˆํ•œ AuthenticationProvider์— ์ž‘์—…์„ ์œ„์ž„ํ•˜๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, ID, Password๊ฐ’์ด ์ •์ƒ์ธ์ง€ ํ™•์ธํ•˜๋Š” ๊ณผ์ •์— ๊ฐœ์ž…ํ•˜์ง€ ์•Š์•„์š”.

๊ด€๋ฆฌ์ž Manager๋‹Œ๊นŒ ์ผ์„ ์‹œํ‚ค๊ธฐ๋งŒ ํ•ด์š”.

AuthenticationManager์—๋Š” List ๋ณ€์ˆ˜๊ฐ€ ์žˆ๋Š”๋ฐ, ํ•œ ๊ฐœ ์ด์ƒ์˜ AuthenticationProvider ๊ฐ์ฒด๋ฅผ ๋‹ด์„ ์ˆ˜ ์žˆ๊ฒŒ ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ํ•ด๋‹น List ์•ˆ์— ์žˆ๋Š” AuthenticationProvider ๊ฐ์ฒด๋“ค ์ค‘ ํ˜„์žฌ ์ธ์ฆ ์ฒ˜๋ฆฌ์— ์ ํ•ฉํ•œ ๊ฐ์ฒด๋ฅผ ์ฐพ์•„ ํ•ด๋‹น AuthenticationProvider์—๊ฒŒ ์ธ์ฆ ์ž‘์—…์„ ์œ„์ž„ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

AuthenticationProvider๋Š” Manager๋กœ ๋ถ€ํ„ฐ ์ธ์ฆ ๊ฐ์ฒด์ธ Authentication์„ ์ „๋‹ฌ ๋ฐ›์•˜๊ณ , ID, Password ๊ฒ€์ฆ ์ž‘์—…์— ๋Œ์ž…ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์ตœ์ดˆ ID(Spring Security์—์„œ๋Š” ID๋ฅผ username ๋ณ€์ˆ˜๋ช…์œผ๋กœ ์ฒ˜๋ฆฌ)๋ฅผ ๊ฒ€์ฆํ•  ๋•Œ, loadUserByUsername()์„ ํ˜ธ์ถœํ•˜๋ฉด์„œ ์ด์šฉ์ž ID๋ฅผ ์ „๋‹ฌํ•ด์ฃผ๊ฒŒ ๋˜์š”.

์ด ์นœ๊ตฌ๋Š” ์‹ค์ œ ์ธ์ฆ ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๊ณ , ์ด์šฉ์ž ์œ ํšจ์„ฑ ๊ฒ€์ฆ(Password ํ™•์ธ ๋“ฑ)์„ ๋‹ด๋‹นํ•˜๊ณ  ์žˆ์–ด์š”.

๋งŒ์•ฝ ํ•ด๋‹น username์œผ๋กœ ๋œ ID๊ฐ’์ด Data Base์— ์กด์žฌํ•˜๋ฉด ์ธ์ฆ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ฒŒ ๋˜๊ณ , ์กด์žฌํ•˜์ง€ ์•Š์œผ๋ฉด UsernameNotFoundException์ด ํ„ฐ์ง€๊ฒŒ ๋ ๊ฑฐ์—์š”.
์ด๋ ‡๊ฒŒ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ๊ทธ ์ฆ‰์‹œ ์ธ์ฆ ์‹คํŒจ ์ฒ˜๋ฆฌ๊ฐ€ ๋˜์–ด๋ฒ„๋ฆฌ๋Š”๋ฐ, UsernamePasswordAuthenticationFilter๊ฐ€ ์ด ์˜ˆ์™ธ๋ฅผ ๋ฐ›์•„์„œ ์ฒ˜๋ฆฌํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์ฆ‰, FailHandler๊ฐ€ ๋ฐ›์•„์„œ ํ›„์† ์ฒ˜๋ฆฌ๋ฅผ ์ง„ํ–‰ํ•˜๊ฒŒ ๋˜์š”.

๋งŒ์•ฝ ID์— ํ•ด๋‹นํ•˜๋Š” username์ด ์กด์žฌํ•œ๋‹ค๋ฉด AuthenticationProvider์—๊ฒŒ ๋ฐ˜ํ™˜์„ ํ•˜๊ฒŒ ๋˜๋Š”๋ฐ, UserDetails ๊ฐ์ฒด Type์œผ๋กœ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

User ๊ฐ์ฒด Type์œผ๋กœ Repository๊ฐ€ ๋„˜๊ฒจ์ฃผ๋”๋ผ๋„ UserDetails Type์œผ๋กœ ํ˜•๋ณ€ํ™˜์„ ํ•ด์„œ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ ๋’ค AuthenticationProvider๋Š” ID๋Š” ๊ฒ€์ฆ์ด ๋๋‚œ ์ƒํƒœ์ด๊ธฐ ๋•Œ๋ฌธ์— Password๋ฅผ ๊ฒ€์ฆํ•˜๋Š” ๋‹จ๊ณ„๋ฅผ ๊ฑฐ์น˜๊ฒŒ ๋˜์š”.
์ด์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ Password ๊ฐ’๊ณผ Data Base์— ์ €์žฅ๋œ Password ๊ฐ’์ด ์ผ์น˜ํ•˜๋Š”์ง€ ๊ฒ€์ฆ์„ ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

๋งŒ์•ฝ Password๊ฐ€ ์ผ์น˜ํ•˜์ง€ ์•Š์œผ๋ฉด BadCredentialsException์ด ํ„ฐ์ง€๊ฒŒ ๋˜์š”. ๊ฒฐ๊ตญ ์ธ์ฆ์€ ์‹คํŒจํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

Password๊ฐ€ ์ผ์น˜ํ•œ๋‹ค๋ฉด ์ธ์ฆ์ด ๋ชจ๋‘ ์„ฑ๊ณตํ•˜๊ฒŒ ๋œ ๊ฒƒ์ด๊ณ , Authentication ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด์„œ UserDetails(์ด์šฉ์ž ์ •๋ณด) ๊ฐ์ฒด์™€ ๊ถŒํ•œ ์ •๋ณด๋ฅผ ๋‹ด์€ authorities ๊ฐ์ฒด๋ฅผ ๋‹ด์€ Token ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

ํ•ด๋‹น ๊ฐ์ฒด๋ฅผ AuthenticationManager์—๊ฒŒ ๋‹ค์‹œ ์ „๋‹ฌํ•ด์ฃผ๊ฒŒ ๋˜๊ณ , AuthenticationManager๋Š” AuthenticationProvider๊ฐ€ ์ „๋‹ฌํ•ด ์ค€ Authentication ๊ฐ์ฒด๋ฅผ UsernamePasswordAuthenticationFilter์—๊ฒŒ ๋‹ค์‹œ ๋ฐ˜ํ™˜ํ•ด ์ค๋‹ˆ๋‹ค.

UsernamePasswordAuthenticationFilter๋Š” ๋งˆ์ง€๋ง‰์œผ๋กœ SecurityContextHolder ์•ˆ์— SecurityContext์— ํ•ด๋‹น ์ธ์ฆ ๊ฐ์ฒด Authentication ๊ฐ์ฒด๋ฅผ ์ €์žฅํ•˜๊ฒŒ ๋˜๊ณ , Client์—๊ฒŒ ์‘๋‹ตํ•ด ์ค๋‹ˆ๋‹ค.










    ๐Ÿ”ฝ  ์ธ์ฆ ๊ด€๋ฆฌ์ž

        ๐Ÿ“ฆ AuthenticationManager


1. AuthenticationProvider ๋ชฉ๋ก ์ค‘์—์„œ ์ธ์ฆ ์ฒ˜๋ฆฌ ์š”๊ฑด์— ๋งž๋Š” AuthenticatonProvider๋ฅผ ์ฐพ์•„ ์ธ์ฆ ์ฒ˜๋ฆฌ ์œ„์ž„.
2. ๋ถ€๋ชจ ProviderManager๋ฅผ ์„ค์ • AuthenticationProvider ๊ณ„์† ํƒ์ƒ‰ ๊ฐ€๋Šฅ.

AutenticationManager๋Š” UsernamePasswordAuthenticationFilter(Form ์ธ์ฆ ์ฒ˜๋ฆฌ Filter)๋กœ ๋ถ€ํ„ฐ ์ธ์ฆ ์ฒ˜๋ฆฌ๋ฅผ ์ฒซ๋ฒˆ์งธ๋กœ ์œ„์ž„ ๋ฐ›๋Š” ์นœ๊ตฌ์—์š”. AutenticationManager๋Š” Interface๋กœ ๋˜์–ด ์žˆ์–ด์š”.
์ด๋ฅผ ๊ตฌํ˜„ํ•œ ๊ตฌํ˜„์ฒด๊ฐ€ ProviderManager์—์š”. ๋˜ํ•œ, ์‹ค์ œ์ ์œผ๋กœ ์ธ์ฆ ์ฒ˜๋ฆฌ๋ฅผ ํ•˜์ง€๋Š” ์•Š๊ณ , ProviderManager์—๊ฒŒ ์œ„์ž„ํ•˜๋Š” ์—ญํ• ๋งŒ ํ•ด์š”.

์ตœ์ดˆ ์ด์šฉ์ž๊ฐ€ ์ธ์ฆ ์š”์ฒญ์„ ํ•  ๋•Œ, Spring Security๋Š” ์—ฌ๋Ÿฌ๊ฐœ์˜ ์ธ์ฆ ์ฒ˜๋ฆฌ ๋ฐฉ์‹์ด ์žˆ์–ด์š”.
์˜ˆ๋ฅผ ๋“ค์–ด ์ด์šฉ์ž๊ฐ€ Form ์ธ์ฆ ๋ฐฉ์‹์œผ๋กœ ์ธ์ฆ ์š”์ฒญ์„ ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ–ˆ์„ ๋•Œ, UsernamePasswordAuthenticationFilter๊ฐ€ ProviderManager๋ฅผ ํ˜ธ์ถœํ•˜๊ฒŒ ๋˜์š”. ํ˜ธ์ถœํ•  ๋•Œ, Authentication(์ธ์ฆ ๊ฐ์ฒด)๋ฅผ ํ•จ๊ป˜ ์ „๋‹ฌํ•ด ์ค๋‹ˆ๋‹ค.

ProviderManager๋Š” Authentication ๊ฐ์ฒด๋ฅผ ๋ฐ›์œผ๋ฉด AuthenticationProvider์—๊ฒŒ ์ „๋‹ฌํ•˜๋Š” ์—ญํ• ๋งŒ ํ•ด์š”.

์ด ๋•Œ, ์—ฌ๋Ÿฌ AuthenticationProvider๊ฐ€ ์žˆ๋Š”๋ฐ,์„ ํƒ ๊ธฐ์ค€์€ Form ์ธ์ฆ์ธ์ง€ RememberMe ์ธ์ฆ ์ธ์ง€ ๋“ฑ๋“ฑ์— ๋งž๋Š” AuthenticationProvider๋ฅผ ์„ ํƒํ•˜๊ฒŒ ๋˜์–ด ์žˆ์–ด์š”.

๋งŒ์•ฝ Form ์ธ์ฆ ๋ฐฉ์‹์ผ ๋•Œ๋Š”, DaoAuthenticationProvider๋ฅผ ์ฐพ์•„ ์ธ์ฆ ์ฒ˜๋ฆฌ ์œ„์ž„์„ ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
๋˜ํ•œ, RemeberMe ์ธ์ฆ ๋ฐฉ์‹์ผ ๋•Œ๋Š”, RememberMeAuthenticationProvider๋ฅผ ์ฐพ์•„ ์ธ์ฆ ์ฒ˜๋ฆฌ ์œ„์ž„์„ ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์ด์šฉ์ž๊ฐ€ ๋งŒ์•ฝ Oauth ์ธ์ฆ์„ ์š”์ฒญํ–ˆ์„ ๋•Œ๋Š” ProviderManager๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” AuthenticationProvider ์ค‘์— Oauth ์ธ์ฆ์„ ์ฒ˜๋ฆฌํ•  ๊ฐ์ฒด๊ฐ€ ์—†์–ด์š”. ์ด ๋•Œ๋Š” ProviderManager๊ฐ€ parent ์†์„ฑ์ด ์žˆ๋Š”๋ฐ, ์ด๋Š” AuthenticationManager Type์˜ ์†์„ฑ์„ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋Š” ์†์„ฑ์ด๊ณ , ProviderManager Type์— ๊ฐ์ฒด๋ฅผ ์ €์žฅํ•  ์ˆ˜ ์žˆ์–ด์š”.

Spring Security๊ฐ€ ์ดˆ๊ธฐํ™” ๋  ๋•Œ, parent ์†์„ฑ์— ๋ถ€๋ชจ ๊ฒฉ์ธ ProviderManager ๊ฐ์ฒด๋ฅผ ์ €์žฅํ•˜๊ฒŒ ๋˜์š”.
๋˜ํ•œ, ProviderManager๊ฐ์ฒด ์•ˆ์—๋Š” OauthAuthenticationProvider ๊ฐ์ฒด๊ฐ€ ์žˆ๊ณ , ์ €์žฅํ•  ์ˆ˜ ์žˆ์–ด์š”.
๊ทธ๋ฆฌ๊ณ  ๋‚˜์„œ  OauthAuthenticationProvider ์ธ์ฆ ์ฒ˜๋ฆฌ๋ฅผ ์œ„์ž„ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.







    ๐Ÿ”ฝ  ์ธ์ฆ ๊ด€๋ฆฌ์ž

        ๐Ÿ“ฆ AuthenticationProvider


AuthenticationProvider๋Š” ์ธ์ฆ ์ฒ˜๋ฆฌ๋ฅผ ํ•  ๋•Œ, ๊ฐ€์žฅ ํ•ต์‹ฌ์ ์ธ ์—ญํ• ์„ ํ•˜๊ณ  ์žˆ๋Š” ์นœ๊ตฌ์ž…๋‹ˆ๋‹ค.

AuthenticationProvider๋ฅผ ํ†ตํ•ด์„œ ID, Password ์™ธ์— ์ถ”๊ฐ€ ์ธ์ฆ์— ๊ด€๋ จ ๊ฒ€์ฆ์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด์š”.
AuthenticationProvider ๋˜ํ•œ, Interface๋กœ ๋งŒ๋“ค์–ด์ ธ ์žˆ์–ด์š”.

AuthenticationProvider ์•ˆ์—๋Š” ๋‘ ๊ฐœ์˜ ์ถ”์ƒ Method๊ฐ€ ์ œ๊ณต ๋˜๋Š”๋ฐ, authenticate(Authentication authentication)์™€ supports(Authentication authentication)๊ฐ€ ์žˆ์–ด์š”. ๋‘ ๊ฐœ Method๋Š” ๋ชจ๋‘ ๋งค๊ฐœ ๋ณ€์ˆ˜๋กœ Authentication ์ฆ‰,
์ธ์ฆ ๊ฐ์ฒด๋ฅผ ๋ฐ›๋„๋ก ๋˜์–ด ์žˆ์–ด์š”.

authenticate(Authentication authentication)๋Š” ์‹ค์ œ ์ธ์ฆ์ฒ˜๋ฆฌ๋ฅผ ๋‹ด๋‹นํ•˜๊ณ  ์žˆ๊ณ , supports(Authentication authentication)๋Š” ํ˜„์žฌ Form ์ธ์ฆ, RememberMe ์ธ์ฆ๊ณผ ๊ฐ™์€ ์ธ์ฆ์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ์กฐ๊ฑด ํ˜น์€ ๊ธฐ์ค€ ๋“ฑ์„ ๊ฒ€์ฆํ•˜๋Š” ์—ญํ• ์„ ํ•˜๊ณ  ์žˆ์–ด์š”.

authenticate(Authentication authentication)์€ ๋งค๊ฐœ ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌ ๋ฐ›์€ Authentication ์ธ์ฆ ๊ฐ์ฒด (ID, Password ๋“ฑ์ด ๋‹ด๊น€)๋ฅผ ๊ฐ€์ง€๊ณ , ID, Password, ์ถ”๊ฐ€ ๊ฒ€์ฆ์„ ํ•˜๊ณ  ์žˆ์–ด์š”.

ID ๊ฒ€์ฆ์„ ํ•  ๋•Œ๋Š” UserDetailsService Interface์—์„œ Data Base ๋“ฑ์— ์ €์žฅ๋œ ID ๊ฐ’์ด ์กด์žฌํ•˜๋Š”์ง€ ๊ฒ€์ฆํ•˜๋Š” ์—ญํ• ์„ ํ•˜๊ณ , ์žˆ๋‹ค๋ฉด ํ•ด๋‹น ์ด์šฉ์ž์˜ USER ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ด์„œ UserDetails ๊ฐ์ฒด Type์œผ๋กœ ๋ณ€ํ™˜ํ•ด์„œ AuthenticationProvider์—๊ฒŒ ์ „๋‹ฌ ํ•˜๊ณ  ์žˆ์–ด์š”.

Password ๊ฒ€์ฆ์€ UserDetailsService์—๊ฒŒ ๋ฐ˜ํ™˜ ๋ฐ›์€ UserDetails ๊ฐ์ฒด Type์˜ ๊ฐ์ฒด ์•ˆ์— Password ๊ฐ’์ด ์žˆ๋Š”๋ฐ, authenticate(Authentication authentication)์—์„œ ์ „๋‹ฌ ๋ฐ›์€ Authentication ๊ฐ์ฒด ์•ˆ์— ์žˆ๋Š” Password ๊ฐ’๊ณผ
์„œ๋กœ ๋น„๊ตํ•˜๋Š” ์ž‘์—…์„ ํ•˜๋Š”๋ฐ, Password Encoder๋ฅผ ํ†ตํ•ด ์•”ํ˜ธํ™”๋ฅผ ํ•˜๋Š”๋ฐ, Hash ํ•จ์ˆ˜๋กœ ์•”ํ˜ธํ™”๋œ Password๋ฅผ ๋ณตํ˜ธํ™”ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ ์„œ๋กœ ๊ฐ™์€์ง€ ๋น„๊ต๋งŒ ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

๋งŒ์•ฝ ๋‹ค๋ฅด๋‹ค๋ฉด BadCredentialException์ด ํ„ฐ์ง€๊ฒŒ ๋˜๊ณ , ID ๊ฒ€์ฆ์ด ์‹คํŒจํ•˜๋ฉด UserNotFoundException์ด ํ„ฐ์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

๋ชจ๋“  ๊ฒ€์ฆ์ด ์ •์ƒ์ ์œผ๋กœ ๋๋‚˜๊ฒŒ ๋˜๋ฉด AuthenticationProvider๋Š” ์ตœ์ข…์ ์œผ๋กœ Authentication ์ธ์ฆ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š”๋ฐ, ์ด์šฉ์ž๊ฐ€ ์ธ์ฆ์— ์„ฑ๊ณตํ•œ USER ๊ฐ์ฒด์™€ ๊ถŒํ•œ ๋ชฉ๋ก์ด ๋‹ด๊ธด authorities Listํ˜• ๊ฐ์ฒด๋ฅผ ์ €์žฅํ•˜์—ฌ AuthenticationProvider์—๊ฒŒ ์ธ์ฆ ์ฒ˜๋ฆฌ๋ฅผ ์œ„์ž„ํ•œ AuthenticationManager์—๊ฒŒ ์ „๋‹ฌํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.







    ๐Ÿ”ฝ  ์ธ๊ฐ€ ๊ฐœ๋… ๋ฐ Filter ์ดํ•ด

์ธ๊ฐ€๋ž€? ์ด์šฉ์ž์—๊ฒŒ ๋ฌด์—‡์ด ํ—ˆ๊ฐ€ ๋˜์—ˆ๋Š”์ง€ ์ฆ๋ช…ํ•˜๋Š” ๊ฒƒ. (๊ถŒํ•œ)

        ๐Ÿ“ฆ Authorization


์ตœ์ดˆ ์ธ์ฆ ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๊ณ , ์ธ๊ฐ€ ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๊ฒŒ ๋˜๋Š”๋ฐ, ์‚ฌ์šฉ์ž๊ฐ€ ์–ด๋–ค ์ž์›์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•œ ์š”์ฒญ์„ ํ•  ๋•Œ, Authenticated ์ฆ‰, ์‚ฌ์šฉ์ž๊ฐ€ ์ธ์ฆ์„ ๋ฐ›์•˜๋Š”์ง€ ๋ฐ›์ง€ ์•Š์•˜๋Š”์ง€๋ฅผ ๋จผ์ € ํ™•์ธํ•˜๊ฒŒ ๋˜๊ณ , ์ธ์ฆ์„ ๋ฐ›์€ ์‚ฌ์šฉ์ž๊ฐ€ ๋‹ค์‹œ ์–ด๋–ค ์ž์›์— ์ ‘๊ทผํ•˜๋ ค๊ณ  ํ•  ๋•Œ, ํ•ด๋‹น ์‚ฌ์šฉ์ž๊ฐ€ ๊ฐ€์ง„ ๊ถŒํ•œ์ด ์š”์ฒญํ•˜๋Š” ์ž์›์ด ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ถŒํ•œ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ์ž๊ฒฉ์ด ์žˆ๋Š”์ง€๋ฅผ ํ™•์ธํ•˜์—ฌ ์ตœ์ข… ์ ‘๊ทผ ์—ฌ๋ถ€๋ฅผ ํŒ๋‹จํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

Spring Security๋Š” ์–ด๋–ค ๊ถŒํ•œ ๊ณ„์ธต์„ ์ง€์›ํ•˜๊ณ  ์žˆ์„๊นŒ์š”?


1. Web Layer (์›น ๊ณ„์ธต)

   • URI ์š”์ฒญ์— ๋”ฐ๋ฅธ Menu, ํ™”๋ฉด ๋‹จ์œ„ Level ๋ณด์•ˆ.
   • ์ด์šฉ์ž๊ฐ€ ํŠน์ • URI์— ์ ‘๊ทผ ์š”์ฒญ์„ ๋ณด๋ƒˆ์„ ๋•Œ, ํ•ด๋‹น URI์— ๊ถŒํ•œ๊ณผ ์ด์šฉ์ž ๊ถŒํ•œ ๋น„๊ตํ•˜์—ฌ ์ ‘๊ทผ ์—ฌ๋ถ€ ํŒ๋‹จ.

2. Service Layer (์„œ๋น„์Šค ๊ณ„์ธต)

   • ํ™”๋ฉด ๋‹จ์œ„๊ฐ€ ์•„๋‹Œ Method์™€ ๊ฐ™์€ ๊ธฐ๋Šฅ ๋‹จ์œ„ Level ๋ณด์•ˆ.
   • ์ด์šฉ์ž๊ฐ€ ํŠน์ • Method(Method ์œ„์— ๊ถŒํ•œ ์„ค์ •)์—์„œ ์ œ๊ณตํ•˜๋Š” Service์— ์ ‘๊ทผ ์š”์ฒญ์„ ๋ณด๋ƒˆ์„ ๋•Œ,
      ํ•ด๋‹น Method ๊ถŒํ•œ๊ณผ ์ด์šฉ์ž ๊ถŒํ•œ ๋น„๊ต ์ ‘๊ทผ ์—ฌ๋ถ€ ํŒ๋‹จ.

2. Domain Layer (๋„๋ฉ”์ธ ๊ณ„์ธต - Access Control List, ์ ‘๊ทผ ์ œ์–ด ๋ชฉ๋ก)

   • ๊ฐ์ฒด ๋‹จ์œ„ Level ๋ณด์•ˆ.
   • ์ด์šฉ์ž๊ฐ€ File, Data Base์™€ ๊ฐ™์€ Application์— ์“ฐ๊ธฐ ์ž‘์—…์„ ํ•˜๋ ค๊ณ  ํ•  ๋•Œ,
      ํ•ด๋‹น Domain์— ์„ค์ •๋œ ๊ถŒํ•œ๊ณผ ์ด์šฉ์ž ๊ถŒํ•œ ๋น„๊ต ์ ‘๊ทผ ์—ฌ๋ถ€ ํŒ๋‹จ.

 

 

 

 

        ๐Ÿ“ฆ FilterSecurityInterceptor

1. ๋งˆ์ง€๋ง‰์— ์œ„์น˜ํ•œ Filter ์ธ์ฆ๋œ ์ด์šฉ์ž์— ๋Œ€ํ•˜์—ฌ ํŠน์ • ์š”์ฒญ์˜ ์Šน์ธ / ๊ฑฐ๋ถ€ ์—ฌ๋ถ€๋ฅผ ์ตœ์ข… ๊ฒฐ์ •.
2. ์ธ์ฆ ๊ฐ์ฒด(Authentication) ์—†์ด ๋ณดํ˜ธ ์ž์›์— ์ ‘๊ทผ ์‹œ๋„ ์‹œ AuthenticationException ๋ฐœ์ƒ.
3. ์ธ์ฆ ๋’ค ์ž์› ์ ‘๊ทผ ๊ฐ€๋Šฅ ๊ถŒํ•œ์ด ์กด์žฌํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ AccessDeniedException ๋ฐœ์ƒ.
4. ๊ถŒํ•œ ์ œ์–ด ๋ฐฉ์‹ ์ค‘ HTTP(URI ๋ฐฉ์‹) ์ž์› ๋ณด์•ˆ ์ฒ˜๋ฆฌ ๋‹ด๋‹น.
5. ๊ถŒํ•œ ์ฒ˜๋ฆฌ๋ฅผ AccessDecisionManager์—๊ฒŒ ์œ„์ž„.



์ตœ์ดˆ ์ด์šฉ์ž๊ฐ€ ํŠน์ • ์ž์› ์ ‘๊ทผ์„ ์œ„ํ•ด ์š”์ฒญ์„ ๋ณด๋‚ด๊ณ  ์žˆ์–ด์š”.

FilterSecurityIntercetptor๋Š” ์ด ์š”์ฒญ์„ ๋ฐ›์•„ ์ธ์ฆ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
์ธ์ฆ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•  ๋•Œ, ์ธ์ฆ ๊ฐ์ฒด(Authentication)๊ฐ€ ์กด์žฌํ•˜๋Š”์ง€ ํ™•์ธํ•˜๊ฒŒ ๋˜๊ณ , ์ธ์ฆ ๊ฐ์ฒด๊ฐ€ ์—†๋‹ค๋ฉด AuthenticationException ์ฆ‰, ์ธ์ฆ ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ ์‹œํ‚ค๊ฒŒ ๋˜์š”. ํ•ด๋‹น Exception์€ ExceptionTranslationFilter๊ฐ€ ๋ฐ›์•„ ํ›„์† ์ž‘์—… ์˜ˆ๋ฅผ ๋“ค์–ด Login Page๋กœ ๋‹ค์‹œ ์ด๋™์„ ์‹œํ‚ค๋Š” ๋“ฑ์— ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•˜๊ฒŒ ๋˜์š”.

์ธ์ฆ ๊ฐ์ฒด๋Š” SecurityContext ์•ˆ์— ์ธ์ฆ์„ ๋ฐ›์•˜์„ ๋•Œ, ์ €์žฅ์ด ๋˜๋Š” ๊ฒƒ์„ ์šฐ๋ฆฌ๋Š” ๊ณต๋ถ€ํ–ˆ์–ด์š”.
๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ํ•ด๋‹น ์ด์šฉ์ž๊ฐ€ ์ธ์ฆ์„ ๋ฐ›์•˜๋‹ค๋ฉด ์ธ์ฆ ๊ฐ์ฒด๋Š” ์กด์žฌํ•˜๊ฒŒ ๋  ๊ฒƒ์ด์—์š”.

์ธ์ฆ ๊ฐ์ฒด๊ฐ€ ์กด์žฌํ•œ๋‹ค๋ฉด SecurityMetadataSource ๊ฐ์ฒด์—์„œ ์ด์šฉ์ž๊ฐ€ USER๋ผ๋Š” URI๋กœ ์ ‘๊ทผํ–ˆ์„ ๋•Œ, ํ•ด๋‹น URI์— ์ ‘๊ทผ ๊ฐ€๋Šฅ ๊ถŒํ•œ์ด ์žˆ์„ ๊ฑฐ๊ณ , ํ•ด๋‹น URI์— ๋“ฑ๋ก๋œ ๊ถŒํ•œ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.

์ฆ‰, ์ด์šฉ์ž๊ฐ€ ์š”์ฒญํ•œ URI์— ํ•„์š”ํ•œ ๊ถŒํ•œ ์ •๋ณด ์กฐํšŒ๋ฅผ ํ•œ ๋’ค ์ „๋‹ฌํ•˜๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.

๋งŒ์•ฝ ํ•ด๋‹น URI์— ๊ถŒํ•œ ์ •๋ณด๊ฐ€ Null์ผ ๊ฒฝ์šฐ ๊ถŒํ•œ ์‹ฌ์‚ฌ๋ฅผ ํ•˜์ง€ ์•Š๊ณ , ์ž์›์— ์ ‘๊ทผ์„ ํ—ˆ์šฉ ์‹œ์ผœ์ค๋‹ˆ๋‹ค.

URI์— ๊ถŒํ•œ ์ •๋ณด๊ฐ€ ์žˆ๋‹ค๋ฉด SecurityMetadataSource๋Š” ํ•ด๋‹น URI์— ๊ถŒํ•œ ์ •๋ณด๋ฅผ AccessDecisionManager์—๊ฒŒ ์ „๋‹ฌ์„ ํ•ด์ฃผ๊ฒŒ ๋˜์š”.

AccessDecisionManager(์ตœ์ข… ์‹ฌ์˜ ๊ฒฐ์ •์ž)๋Š” ์ธ๊ฐ€ ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๊ฒŒ ๋˜๋Š”๋ฐ, ๋‚ด๋ถ€์ ์œผ๋กœ AccessDecisionVoter(์‹ฌ์˜์ž) ๊ฐ์ฒด์— ์ธ๊ฐ€ ๊ด€๋ จ ๋น„๊ต๋ฅผ ์š”์ฒญํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

AccessDecisionVoter๋Š” ํ•ด๋‹น URI์— ์ด์šฉ์ž๊ฐ€ ์ ‘๊ทผํ•  ๊ถŒํ•œ์ด ์žˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ํŒ๋‹จํ•˜๊ณ , ์Šน์ธ ํ˜น์€ ๊ฑฐ๋ถ€์— ๋Œ€ํ•œ ์˜์‚ฌ ๊ฒฐ์ •์„ ํ•˜์—ฌ AccessDecisionManager์—๊ฒŒ ์ „๋‹ฌํ•ด ์ฃผ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

AccessDecisionManager๋Š” ์ „๋‹ฌ ๋ฐ›์€ ๊ฒฐ๊ณผ๊ฐ’์„ ๊ฐ€์ง€๊ณ , ์ตœ์ข…์ ์œผ๋กœ ํ•ด๋‹น ์ด์šฉ์ž๊ฐ€ ํ•ด๋‹น URI์— ์ ‘๊ทผ์„ ํ—ˆ์šฉํ• ์ง€ ๋ง์ง€๋ฅผ ํŒ๋‹จํ•˜๊ฒŒ ๋˜๋Š”๋ฐ, ์ ‘๊ทผ์„ ๊ฑฐ๋ถ€ํ•˜๊ฒŒ ๋˜๋ฉด AccessDeniedException์„ ํ„ฐํŠธ๋ฆฌ๊ฒŒ ๋˜๊ณ , ์ด Exception์„ ExceptionTranslationFilter์—๊ฒŒ ์ „๋‹ฌํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์ ‘๊ทผ์ด ํ—ˆ์šฉ๋˜์—ˆ๋‹ค๋ฉด? ์ด์šฉ์ž๋Š” ์ž์›์— ์ ‘๊ทผ์„ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋  ๊ฑฐ์—์š”.


 


์ธ๊ฐ€ ์ฒ˜๋ฆฌ ๊ณต๋ถ€๋ฅผ ์œ„์— ์œ„์™€ ๊ฐ™์ด SecurityConfig CODE๋ฅผ ์ž‘์„ฑํ•ด ์ฃผ์—ˆ์–ด์š”.
/user ๋ผ๋Š” URI์— ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ๊ถŒํ•œ์€ USER ์ด๊ณ , ๋‚˜๋จธ์ง€๋Š” ๋ชจ๋‘ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ์ฒ˜๋ฆฌ๊ฐ€ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.


 




 

USER ๊ถŒํ•œ์„ ๊ฐ€์ง„ user ๊ณ„์ •์œผ๋กœ ์ธ์ฆ์„ ๋ฐ›๊ณ , /user๋กœ ์ ‘๊ทผํ–ˆ์„ ๋•Œ, ์œ„์™€ ๊ฐ™์ด ์ •์ƒ ์ ‘๊ทผ ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด์š”.

 

 

ํ•˜์ง€๋งŒ, /admin/pay๋Š” ADMIN ๊ถŒํ•œ๋งŒ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•œ๋ฐ, user ๊ณ„์ •์œผ๋กœ ์ ‘๊ทผ์„ ํ•˜๋ ค๊ณ  ํ–ˆ์„ ๋•Œ ์œ„์™€ ๊ฐ™์ด ์ ‘๊ทผ์ด ๋ถˆ๊ฐ€ํ•œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด์š”.

 

๐Ÿ’ก ์ฐธ๊ณ  ์‚ฌํ•ญ

403 Forbidden

HTTP 403 Forbidden ํด๋ผ์ด์–ธํŠธ ์˜ค๋ฅ˜ ์ƒํƒœ ์‘๋‹ต ์ฝ”๋“œ๋Š” ์„œ๋ฒ„์— ์š”์ฒญ์ด ์ „๋‹ฌ๋˜์—ˆ์ง€๋งŒ, ๊ถŒํ•œ ๋•Œ๋ฌธ์— ๊ฑฐ์ ˆ๋˜์—ˆ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

 

 

 

 

    ๐Ÿ”ฝ  ์ธ๊ฐ€ ๊ฒฐ์ • ์‹ฌ์˜์ž

 


์ตœ์ดˆ FilterSecurityInterceptor(๊ถŒํ•œ ์ฒ˜๋ฆฌ ๋‹ด๋‹น์ž)๊ฐ€ AccessDecisionManager์—๊ฒŒ ์ธ๊ฐ€ ์ฒ˜๋ฆฌ์— ๋Œ€ํ•œ ์ž‘์—…์„ ์œ„์ž„ํ•ฉ๋‹ˆ๋‹ค. ์œ„์ž„ํ•  ๋•Œ, authentication - ์ธ์ฆ ์ •๋ณด, object(FilterInvocation) - ์š”์ฒญ ์ •๋ณด, configAttributes - ๊ถŒํ•œ ์ •๋ณด๋ฅผ ํ•จ๊ป˜ ๋„˜๊ฒจ์ค๋‹ˆ๋‹ค.

AccessDecisionManager๋Š” ์ž์‹ ์ด ๋ณด์œ ํ•œ Voter๋“ค์—๊ฒŒ authentication - ์ธ์ฆ ์ •๋ณด, object(FilterInvocation) - ์š”์ฒญ ์ •๋ณด, configAttributes - ๊ถŒํ•œ ์ •๋ณด๋ฅผ ์ „๋‹ฌํ•˜๋ฉด์„œ ๊ฐ Voter๋“ค ์ฆ‰, AccessDecisionVoter์—๊ฒŒ ๊ถŒํ•œ ํŒ๋‹จ ์‹ฌ์‚ฌ๋ฅผ ์œ„์ž„ํ•ฉ๋‹ˆ๋‹ค.

๊ฐ๊ฐ์˜ AccessDecisionVoter ๋งค๊ฐœ ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌ๋œ ๊ฐ’๋“ค์„ ๊ฐ€์ง€๊ณ , ์ ‘๊ทผ ์—ฌ๋ถ€๋ฅผ ํŒ๋‹จํ•˜๊ณ , ์ ‘๊ทผ ํ—ˆ์šฉ(ACCESS_GRANTED), ์ ‘๊ทผ ๊ฑฐ๋ถ€(ACCESS_DENIED), ์ ‘๊ทผ ๋ณด๋ฅ˜(ACCESS_ABSTAIN) ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

AccessDecisionManager๋Š” ๋ฐ˜ํ™˜๋œ ๊ฒฐ๊ณผ๊ฐ’์„ ๊ฐ€์ง€๊ณ , ์ด์šฉ์ž์˜ ์š”์ฒญ์— ์ ‘๊ทผ์„ ํ—ˆ์šฉํ• ์ง€ ๋ง์ง€๋ฅผ ๊ฒฐ์ •ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
์ตœ์ข…์ ์œผ๋กœ ์Šน์ธ์ด ํŒ๋‹จ๋˜๋ฉด FilterSecurityInterceptor์—๊ฒŒ ACCESS_GRANTED ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๊ณ , ๊ฑฐ๋ถ€๊ฐ€ ๋˜๋ฉด
AccessDeniedException์„ ํ„ฐํŠธ๋ ค ExceptionTranslationFilter์—๊ฒŒ ์ „๋‹ฌํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

 

        ๐Ÿ“ฆ AccessDecisonManager

1. ์ธ์ฆ ์ •๋ณด, ์š”์ฒญ ์ •๋ณด, ๊ถŒํ•œ ์ •๋ณด(๋งค๊ฐœ ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌ)๋ฅผ ์ด์šฉ, ์ด์šฉ์ž์˜ ์ž์› ์ ‘๊ทผ ์—ฌ๋ถ€๋ฅผ ์ตœ์ข… ๊ฒฐ์ •ํ•˜๋Š” ์ฃผ์ฒด.
2. ์—ฌ๋Ÿฌ Voter ๋“ค์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์œผ๋ฉฐ, Voter ๋“ค๋กœ๋ถ€ํ„ฐ ์ ‘๊ทผ ์—ฌ๋ถ€(ํ—ˆ์šฉ, ๊ฑฐ๋ถ€, ๋ณด๋ฅ˜)์— ๊ฐ’์„ ๋ฐ˜ํ™˜๋ฐ›๊ณ , ํŒ๋‹จ ๋ฐ ๊ฒฐ์ •.

3. ์ตœ์ข… ์ ‘๊ทผ ๊ฑฐ๋ถ€ ์‹œ Exception ๋ฐœ์ƒ.
4. ์ ‘๊ทผ ๊ฒฐ์ • ์„ธ๊ฐ€์ง€ ์œ ํ˜•. AccessDecisonManager๋Š” Interface๋กœ ์•„๋ž˜ 3๊ฐ€์ง€ ๊ตฌํ˜„์ฒด ๋ณด์œ .

   • AffirmativeBased : ์—ฌ๋Ÿฌ๊ฐœ์˜ Voter Class ์ค‘ ํ•˜๋‚˜๋ผ๋„ ์ ‘๊ทผ ํ—ˆ๊ฐ€๋กœ ๊ฒฐ๋ก ๋‚˜๋ฉด ์ ‘๊ทผ ํ—ˆ๊ฐ€ ์ฒ˜๋ฆฌ.


   • ConsensusBased : ๋‹ค์ˆ˜ํ‘œ(ํˆฌํ‘œ ๋ฐฉ์‹ - ์Šน์ธ ๋ฐ ๊ฑฐ๋ถ€)์— ์˜ํ•ด ์ตœ์ข… ๊ฒฐ์ • ํŒ๋‹จ.
      - ํˆฌํ‘œ์—์„œ ๊ฒฐ๊ณผ๊ฐ€ ๋™์ผํ•  ๊ฒฝ์šฐ ๊ธฐ๋ณธ์€ ์ ‘๊ทผ ํ—ˆ๊ฐ€์ด๋‚˜, allowIfEqualGrantedDeniedDecisions๋ฅผ false๋กœ ์„ค์ •ํ• 
          ๊ฒฝ์šฐ ์ ‘๊ทผ ๊ฑฐ๋ถ€๋กœ ์ฒ˜๋ฆฌ.



   • UnanimousBased : ๋ชจ๋“  Voter๊ฐ€ ๋งŒ์žฅ์ผ์น˜๋กœ ์ ‘๊ทผ์„ ์Šน์ธํ•ด์•ผํ•˜๋ฉฐ, ๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒฝ์šฐ ์ ‘๊ทผ ๊ฑฐ๋ถ€.



 

 

 

 

        ๐Ÿ“ฆ AccessDecisonVoter

1. ํŒ๋‹จ์„ ์‹ฌ์‚ฌํ•˜๋Š” ์œ„์›. ์ด์šฉ์ž์— ์š”์ฒญ์„ ์ ‘๊ทผ ์—ฌ๋ถ€๋ฅผ ํŒ๋‹จ.
2. Voter๊ฐ€ ๊ถŒํ•œ ๋ถ€์—ฌ ๊ณผ์ •์—์„œ ํŒ๋‹จํ•˜๋Š” ์ž๋ฃŒ.

   • Authentication - ์ธ์ฆ ๊ฐ์ฒด ์ฆ‰, ์ธ์ฆ ์ •๋ณด(USER).
   • FilterInvocation - ์š”์ฒญ ์ •๋ณด (antMatcher("/user)).
   • ConfigAttributes - ๊ถŒํ•œ ์ •๋ณด (hasRole("USER")).

3. ๊ฒฐ์ • ๋ฐฉ์‹

   • ACCESS_GRANTED : ์ ‘๊ทผ ํ—ˆ์šฉ(1).
   • ACCESS_DENIED : ์ ‘๊ทผ ๊ฑฐ๋ถ€ (-1).
   • ACCESS_ABSTAIN : ์ ‘๊ทผ ๋ณด๋ฅ˜ (0).
      - Voter๊ฐ€ ํ•ด๋‹น Type์˜ ์š”์ฒญ์— ๋Œ€ํ•ด ๊ฒฐ์ •์„ ๋‚ด๋ฆด ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ.

 

 

 



    ๐Ÿ”ฝ  Spring Security Filter ๋ฐ ์•„ํ‚คํ…์ฒ˜ ์ •๋ฆฌ

 


์ง€๊ธˆ๊นŒ์ง€ ๊ณต๋ถ€ํ•œ ๋‚ด์šฉ์„ ํ•œ๋ฒˆ ์ •๋ฆฌํ•˜๋Š” ์‹œ๊ฐ„์„ ๊ฐ€์ ธ๋ณผ๊ฒŒ์š”.

๊ฒ€์€์ƒ‰์œผ๋กœ ํ‘œ์‹œ๋œ ๊ฐ Filter๋“ค์„ ๊ธฐ์ค€์œผ๋กœ ์œ„์ชฝ์€ Spring Security๊ฐ€ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ๊ณผ์ •์ด๊ณ , ์•„๋ž˜์ชฝ์€ ๊ฐ Filter๋“ค์ด ์–ด๋–ค ์ž‘์—…์„ ํ•˜๋Š”์ง€ ๋‚˜ํƒ€๋‚ด๊ณ  ์žˆ๋Š” ๋ถ€๋ถ„์ด์—์š”.

์ตœ์ดˆ Spring Security๊ฐ€ ์ดˆ๊ธฐํ™” ๋  ๋•Œ, ๊ฐœ๋ฐœ์ž๊ฐ€ ์ž‘์„ฑํ•œ SecurityConfig (WebSecurityConfigurerAdapter extens) Class๋“ค์—์„œ ์—ฌ๋Ÿฌ๊ฐ€์ง€ API๋ฅผ ์ •์˜ํ•˜๊ณ , ๊ฐ๊ฐ์˜ API๋“ค์ด ์š”์ฒญ์„ ๋ฐ›์•„ ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๊ฒŒ ๊ตฌ์„ฑ์„ ํ•ฉ๋‹ˆ๋‹ค.


Spring Security๊ฐ€ ์ดˆ๊ธฐํ™” ๋  ๋•Œ, SecurityConfig์— ์„ค์ •ํ•œ ๋‚ด์šฉ๊ณผ ๊ตฌ์„ฑ๋Œ€๋กœ ๊ฐ๊ฐ์˜ Filter๋“ค์„ ์ƒ์„ฑํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
์‹ค์ œ๋กœ Filter๊ฐ€ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ์—ญํ• ์„ ํ•˜๋ฉฐ, ์ด Filter๋“ค์€ HttpSecurity๊ฐ€ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

์œ„์˜ ๊ทธ๋ฆผ์ฒ˜๋Ÿผ ๋‘๊ฐœ์˜ SecurityConfig๋ฅผ ๋งŒ๋“ค๊ฒŒ ๋˜๋ฉด ๊ฐœ๋ฐœ์ž๊ฐ€ ์ž‘์„ฑํ•œ๋Œ€๋กœ API ์„ค์ •๋“ค์ด ๋งŒ๋“ค์–ด์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

ํ•ด๋‹น Filter ๋ชฉ๋ก๋“ค์€ WebSecurity ๊ฐ์ฒด์— ์ „๋‹ฌ์ด ๋ฉ๋‹ˆ๋‹ค.
WebSecurity๋Š” FilterChainProxy Bean ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ฒŒ ๋˜๋Š”๋ฐ, ์ด ๋•Œ, ์ƒ์„ฑ์ž์— filter ๋ชฉ๋ก๋“ค์„ ์ „๋‹ฌํ•˜๊ฒŒ ๋˜์š”.

FilterChainProxy๋Š” ์ „๋‹ฌ ๋ฐ›์€ ๊ฐ๊ฐ์˜ Filter๋“ค์„ ๊ฐ€์ง€๊ณ  ์žˆ๊ฒŒ ๋˜๊ฒ ์Šต๋‹ˆ๋‹ค.

DelegatingFilterProxy ๊ฐ์ฒด๋Š” Sevlet Filter์ธ๋ฐ, Spring Secutiry๊ฐ€ ์ดˆ๊ธฐํ™” ๋  ๋•Œ, ์ด๋ฏธ FilterChainProxy๋Š” Bean ๊ฐ์ฒด๋กœ ์ƒ์„ฑ๋œ ์ƒํƒœ์ด๊ณ , springSecurityFilterChain์ด๋ผ๋Š” ์ด๋ฆ„์„ ๊ฐ€์ง„ Bean ๊ฐ์ฒด๋ฅผ ์ฐพ๊ฒŒ ๋˜๋Š”๋ฐ, ๊ทธ ์นœ๊ตฌ๊ฐ€ ๋ฐ”๋กœ FilterChainProxy์—์š”.

DelegatingFilterProxy๋Š” ์ด์šฉ์ž์˜ ์š”์ฒญ์ด ๋“ค์–ด์™”์„ ๋•Œ, ์š”์ฒญ์„ ๋ฐ›์•„ springSecurityFilterChain์ด๋ฆ„์„ ๊ฐ€์ง„ Bean ๊ฐ์ฒด ์ฆ‰, FilterChainProxy์—๊ฒŒ ํ•ด๋‹น ์š”์ฒญ ์ฒ˜๋ฆฌ๋ฅผ ์œ„์ž„ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์—ฌ๊ธฐ๊นŒ์ง€๊ฐ€ Spring Security๊ฐ€ ์ดˆ๊ธฐํ™” ๋  ๋•Œ ์ผ์–ด๋‚˜๋Š” ์ผ์ด์—์š”.

์ดˆ๊ธฐํ™” ๊ณผ์ •์ด ๋๋‚˜๊ณ , ์ด์šฉ์ž๊ฐ€ ์ธ์ฆ ์š”์ฒญ์„ ๋ณด๋‚ด๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

DelegatingFilterProxy๊ฐ€ ์ตœ์ดˆ ์ด์šฉ์ž ์ธ์ฆ ์š”์ฒญ์„ ๋ฐ›๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋’ค FilterChainProxy์—๊ฒŒ ํ•ด๋‹น ์š”์ฒญ์— ๋Œ€ํ•œ ์ฒ˜๋ฆฌ๋ฅผ ์œ„์ž„ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

FilterChainProxy๋Š” ์œ„์—์„œ๋„ ์–ธ๊ธ‰ํ–ˆ๋“ฏ์ด ์ดˆ๊ธฐํ™” ๊ณผ์ •์ด ์ผ์–ด๋‚˜๊ฒŒ ๋˜๋ฉด Filter ๋ชฉ๋ก๋“ค์„ ๊ฐ€์ง€๊ณ  ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ , ๊ฐ๊ฐ์˜ Filter๋“ค์—๊ฒŒ ์ฐจ๋ก€๋Œ€๋กœ ํ•ด๋‹น ์š”์ฒญ ์ •๋ณด๋ฅผ ๋ณด๋‚ด๋ฉด์„œ ํ˜ธ์ถœ์„ ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.


๊ฐ๊ฐ์˜ Filter๋“ค์€ Chain ํ˜•์‹์œผ๋กœ ์ž๊ธฐ ์ž์‹ ์˜ ๊ณผ์—…์ด ๋๋‚˜๋ฉด ๋‹ค์Œ Filter์—๊ฒŒ ์ž‘์—… ์ฒ˜๋ฆฌ๋ฅผ ์œ„์ž„ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์ตœ์ดˆ SecurityContextPersistenceFilter๊ฐ€ ํ˜ธ์ถœ์ด ๋ฉ๋‹ˆ๋‹ค.
SecurityContextPersistenceFilter๋Š” HttpSessionSecurityContextRepository๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์–ด์š”.
HttpSessionSecurityContextRepository๋Š” SecurityContext ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ , SecurityContext๋ฅผ Session์— ์ €์žฅํ•˜๊ณ ,์ €์žฅ๋œ SecurityContext๋ฅผ ์ดˆ๊ธฐํ™” ํ•˜๊ณ ,์ฐธ์กฐ ํ•˜๋Š” ์—ญํ• ์„ ํ•˜๊ณ  ์žˆ์–ด์š”.

loadContext()์—์„œ๋Š” ์ด ์ด์šฉ์ž๊ฐ€ ์ด์ „์— SecurityContext ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋˜์–ด Session์— ์ €์žฅํ•œ ์ด๋ ฅ์ด ์žˆ๋Š”์ง€ ํ™•์ธ์„ ํ•ฉ๋‹ˆ๋‹ค.

์ธ์ฆ ๊ณผ์ •์ด๊ธฐ ๋•Œ๋ฌธ์— ์ด์šฉ์ž์— ๋Œ€ํ•œ Session ์ €์žฅ ์ด๋ ฅ์€ ์—†์„๊ฑฐ์—์š”. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— Create SecurityContext๋ฅผ ํ•˜์—ฌ ์ƒˆ๋กœ์šด SecurityContext ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์ธ์ฆ ์š”์ฒญ ์ด์šฉ์ž, ์ต๋ช… ์ด์šฉ์ž์˜ ๊ฒฝ์šฐ SecurityContext ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด SecurityContextHolder ์•ˆ์— ์ €์žฅํ•˜๋Š” ์—ญํ• ์„ SecurityContextPersistenceFilter๊ฐ€ ๋‹ด๋‹นํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ ๋’ค ๋‹ค์Œ Filter๋กœ ์ž‘์—… ์ˆœ์„œ๊ฐ€ ๋„˜์–ด๊ฐ‘๋‹ˆ๋‹ค.


Logout  Filter๋Š” Logout์„ ์ฒ˜๋ฆฌํ•˜๋Š” Filter์ธ๋ฐ, ํ˜„์žฌ๋Š” ์ธ์ฆ ์š”์ฒญ์ด์ง€ Logout ์š”์ฒญ์ด ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ”๋กœ ๋‹ค์Œ Filter๋กœ ์ž‘์—… ์ˆœ์„œ๋ฅผ ๋„˜๊ฒจ์ค๋‹ˆ๋‹ค.

UsernamePasswordAuthenticationFilter๊ฐ€ Form ์ธ์ฆ ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๋Š” ์ธ์ฆ Filter์ธ๋ฐ, ์ตœ์ดˆ Authentication (์ธ์ฆ ๊ฐ์ฒด)๋ฅผ ๋งŒ๋“ค์–ด ์ด์šฉ์ž๊ฐ€ ์š”์ฒญ ๋•Œ ๋ณด๋‚ธ ID, Password๊ฐ’์„ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ ๋’ค AuthenticationManager ์ธ์ฆ ์ฒ˜๋ฆฌ๋ฅผ ์œ„์ž„ํ•˜๊ฒŒ ๋˜๊ณ , AuthenticationManager๋Š” ๋‹ค์‹œ AuthenticationProvider์—๊ฒŒ ์ธ์ฆ ์ฒ˜๋ฆฌ ์ž‘์—…์„ ์œ„์ž„ํ•ฉ๋‹ˆ๋‹ค.

AuthenticationProvider๋Š” UserDetailsService์™€ ๊ฐ™์€ Class๋ฅผ ์ด์šฉํ•˜์—ฌ ID, Password๋ฅผ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค.
์ธ์ฆ์ด ์™„๋ฃŒ๊ฐ€ ๋˜๋ฉด SecurityContextHolder์•ˆ์— SecurityContext ์•ˆ์— Authentication์„ ์ €์žฅํ•˜๋Š”๋ฐ, ์ด ๋•Œ, ์ด์šฉ์ž์˜ ID, Password, ๊ถŒํ•œ ๋ชฉ๋ก๊ณผ ์ธ์ฆ ์—ฌ๋ถ€ ๊ฐ’ ๋“ฑ์„ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.


SecurityContextPersistenceFiler๊ฐ€ ์ฒ˜์Œ์— SecurityContextHolder์™€ SecurityContext ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์—ˆ๋Š”๋ฐ, ์ด๋ฅผ ๊บผ๋‚ด์™€์„œ ์ €์žฅํ•˜๋Š” ๊ฒƒ์ด์—์š”.

๊ธฐ์–ตํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ์€
UsernamePasswordAuthenticationFilter๊ฐ€ ์ธ์ฆ ์ฒ˜๋ฆฌ๊ฐ€ ์™„๋ฃŒ๊ฐ€ ๋˜๋ฉด ๋ฐ”๋กœ SessionManagementFilter๊ฐ€ ๋™์ž‘ํ•˜์—ฌ์„œ ConcurrentSession ๋™์‹œ Session ์ ‘์† ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•˜๊ฒŒ ๋˜๋Š”๋ฐ, ์ด์ „ ์ธ์ฆ ์ฒ˜๋ฆฌ๊ฐ€ ์žˆ์—ˆ๋Š”์ง€ ํ—ˆ์šฉ๋˜๋Š” Session ๊ฐœ์ˆ˜๊ฐ€ ์–ผ๋งˆ์ธ์ง€๋ฅผ ํ™•์ธํ•˜์—ฌ ๋งŒ์•ฝ ๋™์‹œ ์ ‘์† ๊ฐ€๋Šฅ ๊ฐœ์ˆ˜๊ฐ€ ํ•œ ๊ฐœ๋ผ๊ณ  ์„ค์ •ํ–ˆ๋‹ค๊ณ  ๊ฐ€์ •ํ–ˆ์„ ๋•Œ, ์ด ์ „์— ์ธ์ฆ์ด ๋˜์ง€ ์•Š์•˜๋‹ค๋ฉด ๋ณ„๋‹ค๋ฅธ ์กฐ์น˜์—†์ด ํ†ต๊ณผ๊ฐ€ ๋˜๊ณ , SessionFixation์„ ํ†ตํ•ด ์ธ์ฆ์„ ์„ฑ๊ณตํ•œ ์‹œ์ ์— ์ƒˆ๋กญ๊ฒŒ Cookie๊ฐ€ ๋ฐœ๊ธ‰๋˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์ธ์ฆ์„ ์‹œ๋„ํ•˜๊ธฐ ์ „์— Cookie๋Š” ์‚ฌ๋ผ์ง€๊ฒŒ ๋˜๊ณ , ๋‹ค์‹œ Session๊ณผ Cookie๊ฐ€ ์ƒ์„ฑ, ๋ฐœ๊ธ‰๋˜๋„๋ก ์ฒ˜๋ฆฌ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

Register SessionInfo ์ด์ œ Session ์ •๋ณด๊ฐ€ Server์— ํ•˜๋‚˜ ๋“ฑ๋ก๋˜๊ฒŒ ๋˜๋Š” ๊ฒ๋‹ˆ๋‹ค.

์ด ์ฒ˜๋ฆฌ๊ฐ€ ์ธ์ฆ ์ฒ˜๋ฆฌ๊ฐ€ ์ผ์–ด๋‚  ๋•Œ ์ผ์–ด๋‚˜๋Š” ์ž‘์—…์ด์—์š”.

์ธ์ฆ์ด ์„ฑ๊ณต๋œ ์ดํ›„ SuccessHandler๊ฐ€ ํ›„์† ์ž‘์—…์„ ํ•  ๋•Œ, ์ธ์ฆ์„ ์„ฑ๊ณตํ•˜๊ฒŒ ๋˜๋ฉด ์ด์šฉ์ž๊ฐ€ ์š”์ฒญํ•œ Page๋กœ ์ด๋™ํ•˜๊ฒŒ ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ๋•Œ, SecurityContextPersistenceFilter๊ฐ€ Client์—๊ฒŒ ์‘๋‹ต์„ ๋ณด๋‚ด๊ธฐ ์ „์— Session์— SecurityContext ๊ฐ์ฒด๋ฅผ ์ €์žฅํ•˜๋„๋ก ์ฒ˜๋ฆฌ๋ฅผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋’ค Clear SecutiryContext๋ฅผ ์ด์šฉํ•˜์—ฌ SecurityContext ๊ฐ์ฒด๋ฅผ ์ดˆ๊ธฐํ™” ํ•˜๋Š” ์ž‘์—…์„ ์ง„ํ–‰ํ•ด์š”.

์—ฌ๊ธฐ๊นŒ์ง€๊ฐ€ ์ธ์ฆ์„ ์š”์ฒญํ–ˆ์„ ๋•Œ, ์ผ์–ด๋‚˜๋Š” ์ž‘์—…์ด์—์š”.

์ด๋ฒˆ์—๋Š” ์ด์šฉ์ž๊ฐ€ ์š”์ฒญํ•œ Page๋กœ ์ด๋™๋  ๋•Œ, ์–ด๋–ค ์ผ์ด ๋ฐœ์ƒํ•˜๋Š”์ง€ ์•Œ์•„๋ณผ๊ฒŒ์š”.
DelegatingFilterProxy๊ฐ€ ์ตœ์ดˆ ๊ทธ ์š”์ฒญ์„ ๋ฐ›๊ฒŒ ๋˜๊ณ , FilterChainProxy์—๊ฒŒ ํ•ด๋‹น ์š”์ฒญ์— ๋Œ€ํ•œ ์ฒ˜๋ฆฌ๋ฅผ ์œ„์ž„ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

FilterChainProxy๋Š” ์ž์‹ ์—๊ฒŒ ๋“ฑ๋ก๋œ Filter๋“ค์—๊ฒŒ ์ฐจ๋ก€๋Œ€๋กœ ์š”์ฒญ์— ๋Œ€ํ•œ ์ž‘์—… ์ฒ˜๋ฆฌ๋ฅผ ์œ„์ž„ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

SecurityContextPersistenceFilter๊ฐ€ ๋‹ค์‹œ ํ˜ธ์ถœ์ด ๋˜๋Š”๋ฐ, loadContext()์—์„œ ์š”์ฒญ์„ ๋ณด๋‚ธ ์ด์šฉ์ž๊ฐ€ ์ด์šฉ์ž Session์— SecurityContext ๊ฐ์ฒด๋ฅผ ์ €์žฅํ•œ ์ ์ด ์žˆ๋Š”์ง€ ์—†๋Š”์ง€๋ฅผ ํŒ๋‹จํ•ฉ๋‹ˆ๋‹ค.

ํ˜„์žฌ๋Š” ์ธ์ฆ์„ ์„ฑ๊ณตํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— Session์— SecurityContext๊ฐ€ ์ €์žฅ์ด ๋˜์–ด ์žˆ๋Š” ์ƒํƒœ์—์š”.
๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ์ƒˆ๋กœ์šด SecurityContext ๊ฐ์ฒด๋Š” ์ƒ์„ฑํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
๊ทธ๋Ÿฐ ๋’ค ๋‹ค์Œ Filter๋กœ ์ด๋™ํ•˜๋Š”๋ฐ, ์ด๋ฒˆ์—๋„ Logout ์š”์ฒญ์ด ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋˜ ๋‹ค์‹œ ๋‹ค์Œ Filter๋กœ ์ž‘์—…์ด ์ด๋™๋ฉ๋‹ˆ๋‹ค.

UsernamePasswordAuthenticationFilter ์—ญ์‹œ๋„ ์ธ์ฆ ์š”์ฒญ์ด ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋˜ ๋‹ค์‹œ ๋‹ค์Œ Filter๋กœ ์ž‘์—…์ด ์ด๋™๋ฉ๋‹ˆ๋‹ค.

์ด๋ฒˆ์—๋Š” ConcureentSessionFilter(๋™์‹œ์  Session ์ œ์–ด ์ฒ˜๋ฆฌ)๊ฐ€ ๋™์ž‘ํ•˜๊ฒŒ ๋˜์š”.
์ด ์ „์— ์ธ์ฆ์„ ๋ฐ›์€์ ์ด ์žˆ๋Š”์ง€๋ฅผ ํ™•์ธํ•˜๋Š”๋ฐ, ์ด ์ „์— ์ธ์ฆ์„ ๋ฐ›์€ ์ ์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค์Œ Filter๋กœ ์ž‘์—…์ด ์ด๋™๋ฉ๋‹ˆ๋‹ค.

์ด๋ฒˆ์—๋Š” RememberMeAuthenticationFilter๋ฅผ ์•Œ์•„๋ณผ๊ฒŒ์š”.
ํ˜„์žฌ ์š”์ฒญ ์ด์šฉ์ž๊ฐ€ Session์ด ๋งŒ๋ฃŒ ํ˜น์€ ๋ฌดํšจํ™” ๋˜์—ˆ์„ ๋•Œ, Session์•ˆ์— SecurityContext ๊ฐ์ฒด ์•ˆ์— Authentication ์ธ์ฆ ๊ฐ์ฒด๊ฐ€ Null์ผ ๊ฒฝ์šฐ ํ˜ธ์ถœ์ด ๋ฉ๋‹ˆ๋‹ค.

์š”์ฒญ ์ด์šฉ์ž๊ฐ€ Request Header์— remember-me Cookie๋ฅผ ๋‹ด์•„ ๋ณด๋ƒˆ๋‹ค๋ฉด ์ธ์ฆ ์ฒ˜๋ฆฌ๋ฅผ ์‹œ๋„ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

AnonymousAuthenticationFilter๋กœ ์ž‘์—…์ด ๋„˜์–ด๊ฐ€๊ฒŒ ๋˜๋Š”๋ฐ, ์ธ์ฆ ํ˜น์€ ๊ถŒํ•œ ์—†์ด ์–ด๋–ค ์ž์›์— ๋ฐ”๋กœ ์ ‘์†์„ ์‹œ๋„ํ•  ๊ฒฝ์šฐ ๋™์ž‘ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

AnonymousAuthenticationFilter๋Š” AnonymousAuthenticationToken ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด SecurityContext ๊ฐ์ฒด ์•ˆ์— ์ €์žฅํ•˜๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.

SessionManagementFilter๋Š” ์ธ์ฆ์„ ๋ฐ›์„ ๋‹น์‹œ ์œ„์—์„œ ๊ฐ™์ด ์ฒ˜๋ฆฌ๋œ๋‹ค๊ณ  ์–ธ๊ธ‰์„ ํ–ˆ๋Š”๋ฐ, ๋™์ž‘ ์กฐ๊ฑด์€ ์š”์ฒญ ์ด์šฉ์ž Request Header์— Session ์•ˆ์— SecurityContext๊ฐ€ ์—†๊ฑฐ๋‚˜, Null์ผ ๊ฒฝ์šฐ ๋™์ž‘ํ•ด์š”.
์ด์šฉ์ž์˜ Session์ด ๋งŒ๋ฃŒ๋˜์—ˆ์„ ๊ฒฝ์šฐ์ผํ…๋ฐ, ๋‹ค๋ฅธ ์šฐํšŒ์  ๋ฐฉ๋ฒ•์œผ๋กœ ์ ‘๊ทผํ•˜๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

ExceptionTranslationFilter์™€ FilterSecurityInterceptor๊ฐ€ ์ธ์ฆ ์ดํ›„ ์ž์› ์š”์ฒญ์ด ๋“ค์–ด์™”์„ ๋•Œ, ๊ฐ€์žฅ ๋งŽ์€ ์—ญํ• ์„ ํ•˜๋Š” ์นœ๊ตฌ๋“ค์ด์—์š”.

ExceptionTranslationFilter๋Š” ์ธ์ฆ ํ˜น์€ ์ธ๊ฐ€์— ๋Œ€ํ•ด ๋ฌธ์ œ๊ฐ€ ์ƒ๊ฒจ Exception์ด ํ„ฐ์กŒ์„ ๊ฒฝ์šฐ ๋™์ž‘ํ•˜๊ฒŒ ๋˜๋Š”๋ฐ, 
try catch๋กœ ๊ฐ์‹ผ chain.dofilter๋ฅผ ํ†ตํ•ด ๊ทธ ๋‹ค์Œ Filter์ธ FilterSecurityInterceptor๋ฅผ ํ˜ธ์ถœํ•ด ๋ฒ„๋ ค์š”.

FilterSecurityInterceptor(์ธ๊ฐ€ ์ฒ˜๋ฆฌ)๋Š” ๋จผ์ € ์š”์ฒญ ์ด์šฉ์ž์— Request์— ์ธ์ฆ ๊ฐ์ฒด(Authentication)์ด ์žˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ์—†์œผ๋ฉด AuthenticationException์„ ํ„ฐํŠธ๋ฆฌ๊ณ , ExceptionTranslationFilter์—๊ฒŒ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.

๊ทธ ๋‹ค์Œ์€ ์ธ๊ฐ€ ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๋Š”๋ฐ, ์ด๋ฅผ AccessDecisionManager์—๊ฒŒ ์œ„์ž„ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
AccessDecisionManager๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ AccessDecisionVoter๋ฅผ ๊ฐ€์ง€๊ณ , ์ธ๊ฐ€ ์ฒ˜๋ฆฌ ์—ฌ๋ถ€๋ฅผ ๊ฒฐ์ •ํ•˜๊ณ , ๊ฒฐ๊ณผ๊ฐ’์„ FilterSecurityInterceptor์—๊ฒŒ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

๋งŒ์•ฝ ์ธ๊ฐ€ ์ฒ˜๋ฆฌ์— ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค๋ฉด AccessDeniedException์„ FilterSecurityInterceptor๊ฐ€ ํ„ฐํŠธ๋ฆฌ๊ฒŒ ๋˜๊ณ , ์ด๋ฅผ ExceptionTranslationFilter์—๊ฒŒ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.

ExceptionTranslationFilter๋Š” ์ด ๋‘๊ฐ€์ง€ Exception์„ ์ฒ˜๋ฆฌํ•˜๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.

์ด๋ฒˆ์—๋Š” ์ด๋ฏธ ์ธ์ฆ์ด ๋˜์–ด ์žˆ๋Š” ์ƒํƒœ์—์„œ ๋˜ ๋‹ค๋ฅธ ๋ธŒ๋ผ์šฐ์ € ๋“ฑ์œผ๋กœ ์ธ์ฆ์„ ์š”์ฒญํ•  ๋•Œ ๋ฐœ์ƒํ•˜๋Š” ์ž‘์—…์— ๋Œ€ํ•ด ๋‹ค์‹œ ํ•œ๋ฒˆ ๊ณต๋ถ€ํ•ด ๋ณผ๊ฒŒ์š”.

์ด์šฉ์ž๊ฐ€ ์ธ์ฆ ์š”์ฒญ์„ ๋ณด๋‚ด๊ฒŒ ๋˜๊ณ , DelegatingFilterProxy๊ฐ€ ์ตœ์ดˆ ์š”์ฒญ์„ ๋ฐ›์•„ FilterChainProxy์—๊ฒŒ ์š”์ฒญ ์ฒ˜๋ฆฌ๋ฅผ ์œ„์ž„ํ•˜๊ณ , FilterChainProxy๋Š” Filter ๋ชฉ๋ก์— ์žˆ๋Š” Filter๋“ค์—๊ฒŒ ์ž‘์—…์„ ์œ„์ž„ ํ•ฉ๋‹ˆ๋‹ค.

SecurityContextPersistenceFilter, LogoutFilter, UsernamePasswordAuthenticationFilter๋Š” ์ฒซ๋ฒˆ์งธ ์ด์šฉ์ž๊ฐ€ ์ธ์ฆ ์š”์ฒญํ–ˆ์„ ๋•Œ์™€ ๋™์ผํ•˜๊ฒŒ ์ž‘์—…์ด ์ฒ˜๋ฆฌ ๋˜๊ณ , ์ธ์ฆ์€ ์ผ๋‹จ ์„ฑ๊ณต ์ฒ˜๋ฆฌ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ SecurityContextHolder ์•ˆ์— SecurityContext ๊ฐ์ฒด ์•ˆ์— Authentication ์ธ์ฆ ๊ฐ์ฒด๊ฐ€ ๋‹ด๊ธฐ๊ฒŒ ๋˜๊ณ , ์ด๋ฅผ Session์— ์ €์žฅํ•˜๋Š” ์ฒ˜๋ฆฌ๊นŒ์ง€ ์™„๋ฃŒ ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋•Œ, SessionManagementFilter์˜ ConcurrentSession์—์„œ ๋™์ผ ๊ณ„์ •์— Session์€ ํ•˜๋‚˜๋งŒ ์ƒ์„ฑํ•˜๋„๋ก ํ—ˆ์šฉํ•˜๋Š”๋ฐ, ConcurrentSession์—์„œ ๋‘ ๊ฐ€์ง€ ์ „๋žต์— ์˜ํ•ด ์ฒ˜๋ฆฌ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

์ฒซ๋ฒˆ์งธ๋Š” ํ˜„์žฌ ์ด์šฉ์ž ์ธ์ฆ ์‹œ๋„๋ฅผ ์ฐจ๋‹จ (SessionAuthenticationException)์„ ํ•˜๊ฒŒ ๋˜๊ณ , 
๋‘๋ฒˆ์งธ๋Š” ์ด์ „ ์ด์šฉ์ž Session์„ ๋งŒ๋ฃŒ (Session.expireNow) ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

๋งŒ์•ฝ ๋‘๋ฒˆ์งธ ์ฒ˜๋ฆฌ๋ฅผ ํ•œ๋‹ค๋ฉด ํ•ด๋‹น ์ด์šฉ์ž๋Š” ์ฒซ๋ฒˆ์งธ ์ด์šฉ์ž์™€ ๋™์ผํ•˜๊ฒŒ ์š”์ฒญํ•œ URI๋‚˜, ์ •ํ•ด์ ธ์žˆ๋Š” URI๋กœ ์ด๋™ํ•˜๊ฒŒ ๋  ๊ฑฐ์—์š”. ํ•ด๋‹น ์ž‘์—…์€ ์ฒซ๋ฒˆ์งธ ์ธ์ฆ ์ฒ˜๋ฆฌ์™€ ๋™์ผํ•˜๊ฒŒ ์ฒ˜๋ฆฌ๊ฐ€ ๋˜์š”.

์ด ๋•Œ, ์ฒซ๋ฒˆ์งธ ์ธ์ฆ ์ฒ˜๋ฆฌ๋ฅผ ๋ฐ›์€ ์ด์šฉ์ž๊ฐ€ ํŠน์ • URI ์ ‘๊ทผ ์š”์ฒญ์„ ๋ณด๋‚ด๊ฒŒ ๋˜๋ฉด ๋ชจ๋“  Filter์— ์ž‘์—…์„ ๋™์ผํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•œ ๋’ค ConcurrentSessionFilter๊ฐ€ ์š”์ฒญ์„ ๋ฐ›๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์ด ๋•Œ, ConcurrentSessionFilter๋Š” session.isExpired()๋ฅผ ํ†ตํ•ด ํ˜„์žฌ ์ด์šฉ์ž๊ฐ€ Session์ด ๋งŒ๋ฃŒ๋˜์—ˆ๋Š”์ง€๋ฅผ ํŒ๋‹จํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์ฒซ๋ฒˆ์งธ ์ด์šฉ์ž๋Š” ์ด์ „ ์ด์šฉ์ž Session ๋งŒ๋ฃŒ ์ •์ฑ…์— ์˜ํ•ด Session์€ ๋งŒ๋ฃŒ๊ฐ€ ๋˜์—ˆ๊ณ , session.isExpired()์ด True๋กœ ๋ฐ˜ํ™˜๋˜๊ฒŒ ๋˜๋Š”๋ฐ, ๊ทธ๋ ‡๊ฒŒ ๋˜๋ฉด ํ•ด๋‹น ์ด์šฉ์ž๋ฅผ ๋ฐ”๋กœ Logout ์ฒ˜๋ฆฌ๋ฅผ ํ•ด ๋ฒ„๋ฆฌ๊ณ , ์‘๋‹ต์œผ๋กœ Errror Message๋ฅผ ์ฃผ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
๊ทธ๋Ÿฌ๋ฉด ๋‹ค์Œ Filter๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š๊ณ , ์ž‘์—…์€ ์ข…๋ฃŒ ๋ฉ๋‹ˆ๋‹ค.





์ด์ „ ๊ธ€ : [Spring Boot] Spring Security Basic - ๊ธฐ๋ณธ API ๋ฐ Filter ์ดํ•ดํŽธ 

๋‹ค์Œ ๊ธ€ : [Stpring Boot] Spring Security ์‹ค์ „ ํ”„๋กœ์ ํŠธ - ์ธ์ฆ ํ”„๋กœ์„ธ์Šค Form ์ธ์ฆ ๊ตฌํ˜„

 

 

 

 

 

728x90
๋ฐ˜์‘ํ˜•