Backend/Spring

[Spring Security] ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ ์•Œ์•„๋ณด๊ธฐ, ๊ตฌ์กฐ(Filter Chain) ๋ฐ ์ธ์ฆ ๊ณผ์ •

์žฅ์šฉ์„ 2024. 3. 26. 00:22

 

๐Ÿค” ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ?

์Šคํ”„๋ง ๊ธฐ๋ฐ˜์˜ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ณด์•ˆ(์ธ์ฆ๊ณผ ์ธ๊ฐ€)์„ ๋‹ด๋‹นํ•˜๋Š” ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ๋งํ•ฉ๋‹ˆ๋‹ค.

์ธ์ฆ(Authentication)

๋กœ๊ทธ์ธ ๊ณผ์ •์ฒ˜๋Ÿผ ์‚ฌ์šฉ์ž๊ฐ€ ์‹œ์Šคํ…œ์—๊ฒŒ ์ž์‹ ์„ ์‹๋ณ„ํ•  ์ˆ˜ ์žˆ๋Š” ์ž๊ฒฉ์ฆ๋ช…(์•„์ด๋””, ๋น„๋ฐ€๋ฒˆํ˜ธ, ํ† ํฐ ๋“ฑ)์„ ์ œ๊ณตํ•˜๊ณ , ์‹œ์Šคํ…œ์ด ์ด๋ฅผ ํ™•์ธํ•˜๋Š” ๊ณผ์ •์„ ๋งํ•ฉ๋‹ˆ๋‹ค.

์ธ๊ฐ€(Authorization)

์ธ์ฆ๋œ ์‚ฌ์šฉ์ž๊ฐ€ ์–ด๋–ค ๋ฆฌ์†Œ์Šค์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ๋˜๋Š” ์–ด๋–ค ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š”์ง€๋ฅผ ๊ฒ€์ฆํ•˜๋Š” ๊ฒƒ ์ฆ‰, ์ ‘๊ทผ ๊ถŒํ•œ์„ ์–ป๋Š” ์ผ์„ ๋งํ•ฉ๋‹ˆ๋‹ค.

 

๋‹ค์–‘ํ•œ ๋ณด์•ˆ ๊ธฐ๋Šฅ, ์ธ์ฆ ๋ฐฉ์‹, ์ œ์–ด ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์ง€์›ํ•˜์—ฌ ๋ณด๋‹ค ๊ฒฝ๋ ฅํ•œ ๋ณด์•ˆ์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฐœ๋ฐœ์ž๋Š” ์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ์„ ํ†ตํ•ด ๋ณด์•ˆ ๊ด€๋ จ ๋กœ์ง์„ ์ž‘์„ฑํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค๋Š” ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

 

์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•˜์„ ๋•Œ์—๋Š” ์ปจํŠธ๋กค๋Ÿฌ์—์„œ ์ง์ ‘ ์ธ์ฆ๊ณผ ์ธ๊ฐ€๋ฅผ ๊ตฌํ˜„ํ•˜๊ฑฐ๋‚˜ Interceptor๋ฅผ ํ†ตํ•ด ์ปจํŠธ๋กค๋Ÿฌ์— ๋„์ฐฉํ•˜๊ธฐ ์ „ ์ธ์ฆ๊ณผ ์ธ๊ฐ€์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ๋Š” ์Šคํ”„๋ง MVC์™€ ๋ถ„๋ฆฌ๋˜์–ด ์‚ฌ์šฉ์ž์˜ ์š”์ฒญ์ด ๋ณด๋‚ด์ง€๋ฉด DispatcherServlet์— ๋„๋‹ฌํ•˜๊ธฐ ์ „์— ํ•„ํ„ฐ ์ฒด์ธ์„ ํ†ตํ•ด ์ธ์ฆ๊ณผ ์ธ๊ฐ€์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

 

 

โœ” ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ ๊ตฌ์กฐ

๐Ÿ”Ž 1. ํ•„ํ„ฐ ์ฒด์ธ(FilterChain)

 

 

์‚ฌ์šฉ์ž ์š”์ฒญ์‹œ ์„œ๋ธ”๋ฆฟ ์ปจํ…Œ์ด๋„ˆ๋Š” ํ•˜๋‚˜์˜ ํ•„ํ„ฐ ์ฒด์ธ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

ํ•„ํ„ฐ์— ์˜ํ•ด ์š”์ฒญ์ด ํ•„ํ„ฐ๋ง๋˜์—ˆ์„ ๋•Œ, HttpServletResponse๋ฅผ ๋งŒ๋“ค์–ด ์„œ๋ธ”๋ฆฟ ๋Œ€์‹  ์‚ฌ์šฉ์ž์—๊ฒŒ ์‘๋‹ตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฐ˜๋Œ€๋กœ ํ•„ํ„ฐ๋ง ๋˜์ง€์•Š๊ณ  ๋‹ค์Œ์œผ๋กœ ์ „๋‹ฌ๋˜๊ฒŒ ํ•  ๊ฒฝ์šฐ HttpServletRequest๋‚˜ HttpServletResponse์˜ ๋‚ด์šฉ์„ ๋ณ€๊ฒฝํ•˜์—ฌ ๋‹ค์Œ ํ•„ํ„ฐ๋‚˜ ์„œ๋ธ”๋ฆฟ์— ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

๐Ÿ”Ž 2. DelegatingFilterProxy

 

 

์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ๋Š” ํ•„ํ„ฐ์˜ ์ƒ๋ช…์ฃผ๊ธฐ๋ฅผ ์ด์šฉํ•˜์—ฌ ์ธ์ฆ๊ณผ ๊ถŒํ•œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ ํ•„ํ„ฐ์˜ ์ƒ๋ช…์ฃผ๊ธฐ ์‹œ์ ์— ์„œ๋ธ”๋ฆฟ ์ปจํ…Œ์ด๋„ˆ์—์„œ๋Š” ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์— ๋“ฑ๋ก๋œ ๋นˆ์„ ์ธ์‹ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

 

๊ทธ๋ž˜์„œ ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ์—์„œ๋Š” DelegatingFilterProxy๋ผ๋Š” ์„œ๋ธ”๋ฆฟ ํ•„ํ„ฐ ๊ตฌํ˜„์ฒด๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

์„œ๋ธ”๋ฆฟ ๋งค์ปค๋‹ˆ์ฆ˜์„ ํ†ตํ•ด ์„œ๋ธ”๋ฆฟ์˜ ํ•„ํ„ฐ๋กœ ๋“ฑ๋ก๋  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์Šคํ”„๋ง์— ๋“ฑ๋ก๋œ ๋นˆ์„ ๊ฐ€์ ธ์™€ ์˜์กด์„ฑ์„ ์ฃผ์ž…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋ ‡๊ฒŒ DelegatingFilterProxy๋Š” ์„œ๋ธ”๋ฆฟ ์ปจํ…Œ์ด๋„ˆ์˜ ์ƒ๋ช…์ฃผ๊ธฐ์™€ ์Šคํ”„๋ง์˜ ApplicationContext์‚ฌ์ด๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š” ๋‹ค๋ฆฌ ์—ญํ•˜์„ ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

DelegatingFilterProxy์—์„œ๋Š” ์„œ๋ธ”๋ฆฟ ํ•„ํ„ฐ์—์„œ ๋ฐ›์€ ์š”์ฒญ๊ณผ ์‘๋‹ต์„ ์Šคํ”„๋ง ๋นˆ์œผ๋กœ ๋“ฑ๋ก๋œ ํ•„ํ„ฐ๋กœ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.

 

 

๐Ÿ”Ž 3. FilterChainProxy

 

 

DelegatingFilterProxy์˜ ๋‚ด๋ถ€์—๋Š” FilterChainProxy๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

FilterChainProxy๋Š” DelegatingFilterProxy๋ฅผ ํ†ตํ•ด ๋ฐ›์€ ์š”์ฒญ๊ณผ ์‘๋‹ต์„ SecurityFilterChain์— ์ „๋‹ฌํ•˜๊ณ  ์ž‘์—…์„ ์œ„์ž„ํ•˜๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.

๋ฐ”๋กœ SecurityFilterChain์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ์ค‘๊ฐ„์— FilterChainProxy๋ฅผ ๋‘ ์œผ๋กœ์จ ์„œ๋ธ”๋ฆฟ์„ ์ง€์›ํ•˜๋Š” ์‹œ์ž‘์  ์—ญํ• ์„ ํ•˜๊ธฐ ์œ„ํ•ด์„œ์ž…๋‹ˆ๋‹ค.

๋งŒ์•ฝ ์„œ๋ธ”๋ฆฟ์—์„œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค๋ฉด FilterChainProxy์˜ ๋ฌธ์ œ๋ผ๋Š” ๊ฒƒ์„ ๋ฐ”๋กœ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๋˜ํ•œ SecurityFilterChain์ด ์—ฌ๋Ÿฌ ๊ฐœ๋กœ ๊ตฌ์„ฑ๋  ๊ฒฝ์šฐ, DelegatingFilterProxy์—๋Š” FilterChainProxyํ•˜๋‚˜๋งŒ ๋‘๊ณ  ์—ฌ๋Ÿฌ ๊ฐœ์˜ SecurityFilterChain ์ค‘ ์„ ํƒํ•˜์—ฌ ์ž‘์—…์„ ์œ„์ž„ํ• ์ง€ ๊ฒฐ์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

๐Ÿ”Ž 4. SecurityFilterChain

 

 

์ธ์ฆ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ์—ฌ๋Ÿฌ ๊ฐœ์˜ SecurityFilter๋ฅผ ๋‹ด๋Š” ํ•„ํ„ฐ ์ฒด์ธ์ž…๋‹ˆ๋‹ค.

FilterChainProxy๋ฅผ ํ†ตํ•ด ์„œ๋ธ”๋ฆฟ ํ•„ํ„ฐ์™€ ์—ฐ๊ฒฐ๋˜๊ณ , ์–ด๋–ค SecurityFilter๋ฅผ ํ†ตํ•ด ์ธ์ฆ์„ ์ˆ˜ํ–‰ํ• ์ง€ ๊ฒฐ์ •ํ•˜๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.

 

 

์—ฌ๋Ÿฌ ๊ฐœ์˜ SecurityFilterChain์„ ๊ตฌ์„ฑํ•˜์—ฌ ์š”์ฒญ๋˜๋Š” URL์— ๋”ฐ๋ผ ๋‹ค๋ฅธ SecurityFilterChain์ด ์‚ฌ์šฉ๋˜๋„๋ก ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

๐Ÿ”Ž 5. SecurityFilter

์š”์ฒญ์„ ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ ๋ฉ”์ปค๋‹ˆ์ฆ˜์— ๋”ฐ๋ผ ์ฒ˜๋ฆฌํ•˜๋Š” ํ•„ํ„ฐ์ž…๋‹ˆ๋‹ค.

DelegatingFilterProxy์™€ FilterChainProxy๊ฐ€ ์„œ๋ธ”๋ฆฟ๊ณผ ์Šคํ”„๋ง๊ณผ์˜ ์—ฐ๊ฒฐ์„ ๋‹ด๋‹นํ–ˆ๋‹ค๋ฉด, SecurityFilter๋Š” ์‹œํ๋ฆฌํ‹ฐ์˜ ํ•ต์‹ฌ ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์ง€์ ์ž…๋‹ˆ๋‹ค.

 

SecurityFilter๋Š” SecurityFilterChain API๋ฅผ ํ†ตํ•ด FilterChainProxy์— ์‚ฝ์ž…๋˜๊ณ  ์Šคํ”„๋ง ๋นˆ์œผ๋กœ ๋“ฑ๋ก๋ฉ๋‹ˆ๋‹ค.

 

 

โœ” ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ ์ธ์ฆ ๊ณผ์ •

 

1. ์‚ฌ์šฉ์ž์˜ ์ž๊ฒฉ์ฆ๋ช…(์•„์ด๋””, ๋น„๋ฐ€๋ฒˆํ˜ธ)์ด Form์„ ํ†ตํ•ด ์š”์ฒญ๋ฉ๋‹ˆ๋‹ค.

 

2. ์š”์ฒญ์€ AuthenticationFilter๋ฅผ ๊ฑฐ์ณ ์š”์ฒญ๋œ ์ •๋ณด๋ฅผ ํ†ตํ•ด ์ธ์ฆ๋˜๊ธฐ ์ „ UsernamePasswordAuthenticationToken์„ 1์ฐจ๋กœ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

 

3. AuthenticationManager๋Š” ๋“ฑ๋ก๋œ AuthenticationProvider๋“ค์„ ์กฐํšŒํ•˜์—ฌ ์ธ์ฆ์„ ์š”๊ตฌํ•ฉ๋‹ˆ๋‹ค.

 

4. ์‹ค์ œ DB์—์„œ ์‚ฌ์šฉ์ž ์ธ์ฆ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” UserDetailsService์— ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ๋„˜๊ฒจ์ค๋‹ˆ๋‹ค.

 

5. ๋„˜๊ฒจ๋ฐ›์€ ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ํ†ตํ•ด DB์—์„œ ์ฐพ์€ ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ UserDetails ๊ฐ์ฒด๋กœ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

 

6. AuthenticationsProvider๋“ค์€ UserDetails๋ฅผ ๋„˜๊ฒจ๋ฐ›๊ณ  ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ๋น„๊ตํ•ฉ๋‹ˆ๋‹ค.

 public class MemberService implements UserDetailsService {
 
 	@Override
    public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
        Member member = memberRepository.findByEmail(email);

        if( member == null ){
            throw new UsernameNotFoundException(email);
        }

        return new MemberDetails(member); // MemberDetails๋Š” UserDetails์˜ ๊ตฌํ˜„์ฒด
    }
    
}

 

UserDetailsService๋Š” ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€์—์„œ ์ž…๋ ฅํ•œ ์•„์ด๋””๋ฅผ ํ†ตํ•ด loadUserByUsername๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

loadUserByUsername์€ DB์— ์žˆ๋Š” ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ UserDetails ํ˜•ํƒœ๋กœ ๋ฆฌํ„ดํ•ฉ๋‹ˆ๋‹ค.

 

7. AuthenticationsProvider๋“ค์€ ๋ฆฌํ„ด๋œ UserDetails์™€  ์ž…๋ ฅ๋ฐ›์€ ์‚ฌ์šฉ์ž ์ •๋ณด๊ฐ€ ์ผ์น˜ํ•˜๋ฉด ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ๋‹ด์€ Authentication ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

 

[์ธ์ฆ ์„ฑ๊ณต]

8. ์ธ์ฆ์— ์„ฑ๊ณตํ•˜๊ฒŒ ๋˜๋ฉด AuthenticationManager๋Š” ๋ฐ˜ํ™˜๋ฐ›์€ ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ํฌํ•จํ•˜์—ฌ ์ธ์ฆ๋œ ํ›„์˜ UsernamePasswordAuthenticationToken(Authentication)์„ 2์ฐจ๋กœ ์ƒ์„ฑํ•˜๊ณ  AuthenticationFilter๋กœ ๋ณด๋ƒ…๋‹ˆ๋‹ค.

 

9. Authentication๊ฐ์ฒด๋ฅผ SecurityContext์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค, ์ด๋Š” 1์ฐจ ์บ์‹œ์˜ ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•˜๋ฉฐ ์ธ์ฆ ์ดํ›„ ์‚ฌ์šฉ์ž๊ฐ€ ๋‹ค์‹œ ์š”์ฒญ์„ ๋ณด๋‚ด๊ฒŒ ๋˜๋ฉด SecurityContext๊ฐ์ฒด ์•ˆ์— Authentication์ด ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

 

 

 


 

๐Ÿ“š Reference

https://dev-coco.tistory.com/174

https://www.boostcourse.org/web326/lecture/58997?isDesc=false

https://limdevbasic.tistory.com/19

https://docs.spring.io/spring-security/site/docs/5.4.2/reference/html5/#servlet-security-filters