Skip to content

Latest commit

ย 

History

History
163 lines (121 loc) ยท 13.1 KB

Security.md

File metadata and controls

163 lines (121 loc) ยท 13.1 KB

Spring Security๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋Šฅ๋“ค

security-features ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ๋“ค์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋งŒ์•ฝ Spring Security๋ฅผ ์ ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ์œ„์˜ ๊ธฐ๋Šฅ๋“ค ์ค‘ ํ•„์š”ํ•œ ๋ถ€๋ถ„์„ ๋ชจ๋‘ ์†์ˆ˜ ๋‹ค ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‹ˆ ์•ˆ ์“ธ ์ด์œ ๊ฐ€ ์—†๊ฒ ์ฃ ?

๋˜ Security์—์„œ OAuth2๋ฅผ Resource sever ๋กœ์„œ ๊ตฌํ˜„์„ ํ•  ์ˆ˜๋„ ์žˆ๊ณ  Client ๋กœ์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค์–ด ๋‘์—ˆ์Šต๋‹ˆ๋‹ค. Spring Security๋ฅผ ์ด์šฉํ•˜์ง€ ์•Š๊ณ  RestTemplate์ด๋‚˜ WebClient๋กœ OAuth๋ฅผ ์ œ๊ณตํ•˜๋Š” ์„œ๋น„์Šค์— API ์š”์ฒญ์„ ์˜๊ณ  Redirect๋ฅผ ๊ตฌํ˜„ํ•ด OAuth๋ฅผ ์ด์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๊ทธ ๋ชจ๋“  ๊ฒŒ Spring Security์— ๊ตฌํ˜„์ด ๋˜์–ด์žˆ๊ธฐ ๋•Œ๋ฌธ์— Spring Security๋ฅผ ์‚ฌ์šฉํ•ด ์นด์นด์˜ค OAuth ์„œ๋น„์Šค๋ฅผ ์ด์šฉํ•˜์˜€์Šต๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ ์ด์— ๋”ฐ๋ฅธ ๋Œ€๊ฐ€๊ฐ€ ์žˆ๋Š”๋ฐ ๋„ˆ๋ฌด ๋†’์€ ์ถ”์ƒํ™” ์ˆ˜์ค€ ๋•Œ๋ฌธ์— ์—ญ์ถ”์ ์ด ์‰ฝ์ง€๊ฐ€ ์•Š๊ณ  ์ง์ ‘ ๋””๋ฒ„๊น…์„ ํ•˜๋ฉด์„œ ๋”ฐ๋ผ๊ฐ€์ง€ ์•Š์œผ๋ฉด ๊ทธ ํ๋ฆ„์„ ํŒŒ์•…ํ•˜๊ธฐ ์–ด๋ ต๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๐Ÿ˜ญ ๊ทธ๋ž˜์„œ ๋จผ์ € ๊ธฐ๋ณธ์ ์ธ Spring Security ์•„ํ‚คํ…์ฒ˜ ์— ๋Œ€ํ•ด ์•Œ๊ณ  ๊ฐ€์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์˜€๊ณ  ํ•™์Šต ํ›„ ๋””๋ฒ„๊น…์„ ํ•ด๋ณด๋ฉฐ ๋”ฐ๋ผ๊ฐ”์„ ๋•Œ ๋” ๋น ๋ฅด๊ฒŒ ํก์ˆ˜ ํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

Spring Security์˜ ๊ผญ ์•Œ์•„์•ผํ•  ๋‚ด์šฉ

์™œ ์•Œ์•„์•ผ ํ• ๊นŒ?

๊ธฐ๋ณธ์€ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.

์ €๋Š” OAuth๋ฅผ ์ ์šฉํ•˜๊ธฐ ์ „์— ๋จผ์ € Spring Security์˜ ๊ตฌ๋™์›๋ฆฌ์™€ ์•„ํ‚คํ…์ฒ˜์— ๋Œ€ํ•ด ๋จผ์ € ํ•™์Šตํ•˜์˜€์Šต๋‹ˆ๋‹ค. ์ฒ˜์Œ์—๋Š” ๋ฌดํ„ฑ๋Œ€๋กœ ๋ธ”๋กœ๊ทธ์˜ ๊ธ€์„ ๋ณต๋ถ™ํ•˜๋Š” ํ˜•์‹์ด์˜€์Šต๋‹ˆ๋‹ค. ์ฝ”๋“œ๋ฅผ ๊ทธ๋Ÿฐ์‹์œผ๋กœ ๊ธ์–ด์™€ ์‚ฌ์šฉํ•˜๋‹ˆ ๊ทธ์— ๋”ฐ๋ฅธ ๋ถ€์ž‘์šฉ์€ ๋”์šฑ ์ปธ์Šต๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ ๋ถ€์ž‘์šฉ๋“ค์ด ๋งŽ์•˜์ง€๋งŒ ๊ฐ€์žฅ ํฐ ๋‘๊ฐ€์ง€๋ฅผ ๊ณต์œ ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

  • ๊ตฌํ˜„์„ ํ•˜๋Š” ์‚ฌ๋žŒ์ด์ง€๋งŒ OAuth ๋กœ๊ทธ์ธ ํ๋ฆ„์„ ํŒŒ์•…ํ•˜์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ์šฐ๋ฆฌ ํ”„๋กœ๋•ํŠธ ํ™˜๊ฒฝ์—์„œ ํ•„์š”์—†๋Š” ์ฝ”๋“œ๋“ค์ด ์ƒ๊ฒจ๋‚ฌ๊ณ  ๊ทธ ๊ฐ’๋“ค์ด DB์— ์ €์žฅ๋˜๊ธฐ ๊นŒ์ง€ ํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด๋Ÿฐ ๋ถ€์ž‘์šฉ์„ ์—†์• ๊ธฐ ์œ„ํ•ด์„œ๋Š” ํ•™์Šต์ด ๋ฌด์กฐ๊ฑด ์ ์œผ๋กœ ํ•„์š”ํ–ˆ์Šต๋‹ˆ๋‹ค.

๋จผ์ € Spring Security ๋ฅผ ์•Œ๊ธฐ ์ „์— ๋ฏธ๋ฆฌ ์•Œ์•„๊ฐ€๊ณ  ๋“ค์–ด๊ฐ€์•ผํ•  ๊ฐœ๋… ๋ช‡๊ฐ€์ง€๋ฅผ ์†Œ๊ฐœํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์šฉ์–ด

์šฉ์–ด์— ๋Œ€ํ•ด ๋จผ์ € ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ทธ ๋‚˜๋ผ์˜ ์–ธ์–ด๋ฅผ ๋ชจ๋ฅธ๋‹ค๋ฉด ์˜์‚ฌ์†Œํ†ต์ด ๊ฐ€๋Šฅํ• ๊นŒ์š”? ์‹œํ๋ฆฌํ‹ฐ๋ฅผ ์ž˜ ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•ด์„  ๋จผ์ € ์•Œ๊ณ ๊ฐ€์•ผํ•œ๋‹ค ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

  • ์ ‘๊ทผ ์ฃผ์ฒด(Principal): ๋ณดํ˜ธ๋œ ๋Œ€์ƒ์— ์ ‘๊ทผํ•˜๋Š” ์œ ์ €
  • ์ธ์ฆ(Authenticate): ์š”์ฒญ์„ ๋ณด๋‚ธ ์œ ์ €๊ฐ€ ๋ˆ„๊ตฌ์ธ์ง€ ํ™•์ธ(ex. ๋กœ๊ทธ์ธ), ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ์ฃผ์ฒด์ž„์„ ์ฆ๋ช…
  • ์ธ๊ฐ€(Authorization): ํ˜„์žฌ ์œ ์ €๊ฐ€ ์–ด๋–ค ์„œ๋น„์Šค, ํŽ˜์ด์ง€์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๊ถŒํ•œ์„ ๋ถ€์—ฌ
    • ๊ถŒํ•œ: ์ธ์ฆ๋œ ์ฃผ์ฒด๊ฐ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ๊ถŒํ•œ
      • ๋จผ์ € ์ธ์ฆ ๊ณผ์ •์„ ํ†ตํ•ด ์ฃผ์ฒด๊ฐ€ ์ฆ๋ช… ๋œ ์ดํ›„ ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•  ์ˆ˜ ์žˆ์Œ
      • ๊ถŒํ•œ ๋ถ€์—ฌ์—๋„ ๋‘ ๊ฐ€์ง€ ์˜์—ญ์ด ์กด์žฌํ•˜๋Š”๋ฐ ์›น ์š”์ฒญ ๊ถŒํ•œ, ๋ฉ”์†Œ๋“œ ํ˜ธ์ถœ ๋ฐ ๋„๋ฉ”์ธ ์ธ์Šคํ„ด์Šค์— ๋Œ€ํ•œ ์ ‘๊ทผ ๊ถŒํ•œ ๋ถ€์—ฌ๊ฐ€ ์žˆ์Œ +)์ธ์ฆ๊ณผ ๊ถŒํ•œ์„ ๊ตฌ๋ถ„ํ•ด ์ƒ๊ฐํ•˜๋Š” ๊ฒƒ์ด ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ๋ฅผ ์ดํ•ดํ•˜๋Š”๋ฐ ๊ฐ€์žฅ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.
  • ์ฆ๋ช…์„œ(Credential) : ์ธ์ฆ ๊ณผ์ • ์ค‘, ์ฃผ์ฒด๊ฐ€ ๋ณธ์ธ์„ ์ธ์ฆํ•˜๊ธฐ ์œ„ํ•ด ์„œ๋ฒ„์— ์ œ๊ณตํ•˜๋Š” ๊ฒƒ. (ID, Password ๊ฐ™์€ ๊ฒƒ)
  • ๊ถŒํ•œ(authorities) : ์œ ์ €์—๊ฒŒ ์ฃผ์–ด์ง€๋Š” ๊ถŒํ•œ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ๋“ค์–ด roles, scopes

SecurityContextHolder

SecurityContextHolder ๋ ˆํผ๋Ÿฐ์Šค์— ๋ณด๋ฉด SecurityContextHolder ๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ‘œํ˜„ํ•ฉ๋‹ˆ๋‹ค.

At the heart of Spring Securityโ€™s authentication model is the SecurityContextHolder

Spring security ์˜ ํ•ต์‹ฌ์ด๋ผ๊ณ  ํ•  ์ˆ˜์žˆ๋Š”๋ฐ์š”. Spring security ๋Š” SecurityContextHolder๋ฅผ ์ด์šฉํ•ด ์ธ์ฆ๊ฐ์ฒด๋ฅผ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค. SecurityContextHolder๋Š” ์ธ์ฆ๋œ user์˜ details ๋ฅผ ์ €์žฅํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. details ์—๋Š” ์–ด๋–ค Authentication ๊ฐ์ฒด๋ฅผ ์“ฐ๋Š๋ƒ์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง€๋Š”๋ฐ FormLogin์„ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ UserDetails ์— ๋Œ€ํ•œ ๋‚ด์šฉ์ด OAuth2Login์„ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ OAuth2User ์— ๋Œ€ํ•œ ๋‚ด์šฉ์ด ์ €์žฅ๋ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ ํ”„๋กœ๋•ํŠธ์—๋Š” OAuth2 ๋ฅผ ์‚ฌ์šฉํ•˜๋‹ˆ OAuth2User ์•  ๋Œ€ํ•œ ๋‚ด์šฉ์ด ๋“ค์–ด๊ฐ€๊ฒ ์ฃ ?

The SecurityContextHolder is where Spring Security stores the details of who is authenticated. Spring Security does not care how the SecurityContextHolder is populated. If it contains a value, then it is used as the currently authenticated user.

The simplest way to indicate a user is authenticated is to set the SecurityContextHolder directly.

SecurityContextHolder๋Š” ์–ด๋–ป๊ฒŒ ์ €์žฅ๋˜๋Š”์ง€ ๋ฐฉ์‹์—๋Š” ๊ด€์‹ฌ์ด ์—†๋‹ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, SecurityContextHolder ์— ์ธ์ฆ๊ฐ์ฒด๊ฐ€ ์žˆ๋‹ค๋ฉด ๊ทธ ๊ฐ์ฒด๋Š” ์ธ์ฆ๋œ ๊ฐ์ฒด๋ผ๊ณ  ์ƒ๊ฐํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ƒฅ Security FilterChain์— Authentication ํ•˜๋Š” Filter๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ ๊ณผ์ •์„ ๊ฑฐ์น˜์ง€ ์•Š์•„๋„ ์ง์ ‘ SecurityContextHolder ์— set์œผ๋กœ ๋„ฃ์–ด์ค€๋‹ค๋ฉด ๊ทธ ๊ฐ์ฒด๋Š” ์ธ์ฆ๋œ ๊ฐ์ฒด๋ผ๊ณ  ์ƒ๊ฐํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ด ๋ถ€๋ถ„์„ ์ด์šฉํ•ด์„œ JwtAuthenticationFilter ๋ฅผ ๋งŒ๋“ค ๊ฒƒ์ž…๋‹ˆ๋‹ค.

SecurityContextHolder๋ฅผ set ํ•˜๊ธฐ ์œ„ํ•ด์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ณผ์ •์„ ๊ฑฐ์นฉ๋‹ˆ๋‹ค.

SecurityContext context = SecurityContextHolder.createEmptyContext();  // (1) 
Authentication authentication =
    new TestingAuthenticationToken("username", "password", "ROLE_USER"); // (2) 
context.setAuthentication(authentication);

SecurityContextHolder.setContext(context);

SecurityContext๋Š” SecurityContextHolder๋กœ ๋ถ€ํ„ฐ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. SecurityContext๋Š” Authentication ๊ฐ์ฒด๋ฅผ ๊ฐ–๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

  1. ๋น„์–ด์žˆ๋Š” SecurityContext ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์œ„์˜ ๊ณผ์ •์„ SecurityContextHolder.getContext().setAuthentication(authentication) ๋กœ ํ•œ ๋ฒˆ์— ์„ ์–ธํ•˜๋Š” ๊ฑธ ํ”ผํ•˜๋ผ๊ณ  ๋‚˜์™€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ €๋ ‡๊ฒŒ ์„ ์–ธํ•œ๋‹ค๋ฉด ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ์ผ ๊ฒฝ์šฐ ๊ฒฝํ•ฉ์ƒํƒœ(race Condition) ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.
  2. ๊ทธ ํ›„ Authentication์„ ์„ ์–ธํ•ด ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. Authentication์€ ์ธํ„ฐํŽ˜์ด์Šค์ž…๋‹ˆ๋‹ค. Spring Security๋Š” ์–ด๋–ค ์ข…๋ฅ˜์˜ Authentication์ธ์ง€๋Š” ๊ด€์‹ฌ์ด ์—†์Šต๋‹ˆ๋‹ค. Authentication์„ ๊ตฌํ˜„ํ•œ ๊ตฌํ˜„์ฒด์ด๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

Spring Security๋Š” SecurityContextHolder ์— ์ €์žฅ๋œ ๋‚ด์šฉ์„ ์ธ๊ฐ€(Authorization)๋ฅผ ์œ„ํ•ด ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

ThreadLocal

SecurityContextHolder๋ฅผ ์ดํ•ดํ•˜๋Š” ๋ฐ ๊ผญ ํ•„์š”ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. SecurityContextHolder๋Š” ์ „๋žต์ ์œผ๋กœ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•  ๊ฒƒ์ธ์ง€ ์ •ํ•ด์ง‘๋‹ˆ๋‹ค. ๋””ํด๋“œ ๊ฐ’์€ ThreadLocal ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ThreadLocal ์ด๋ž€ ๊ฐ„๋‹จํžˆ ์„ค๋ช…ํ•ด์„œ ์Šค๋ ˆ๋“œ ์ง€์—ญ ๋ณ€์ˆ˜์ž…๋‹ˆ๋‹ค. ๊ฐ™์€ Thread ํ•˜๋Š” Scope ๋‚ด์—์„œ ๊ณต์œ ๋˜์–ด ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋Š” ๊ฐ’์œผ๋กœ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์—์„œ ๊ณต์œ ๋ณ€์ˆ˜์— ์ ‘๊ทผํ•  ์‹œ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ๋™์‹œ์„ฑ ๋ฌธ์ œ์˜ ์˜ˆ๋ฐฉ์„ ์œ„ํ•ด ๋งŒ๋“ค์–ด์กŒ์Šต๋‹ˆ๋‹ค. Security์˜ ThreadLocalSecurityContextH ํด๋ž˜์Šค๋ฅผ ๋ณด๋ฉด ThreadLocal์„ static์œผ๋กœ ์„ ์–ธํ•ฉ๋‹ˆ๋‹ค. ๊ทธ ์ด์œ ๋ฅผ ์ƒ๊ฐํ•ด ๋ณธ๋‹ค๋ฉด ์ด๋Ÿฐ ์ด์œ ์ด์ง€ ์•Š์„๊นŒ ์ƒ๊ฐ๋ฉ๋‹ˆ๋‹ค. Thread๋Š” ThreadLocal์„ Map์œผ๋กœ ๊ด€๋ฆฌํ•˜๊ณ  ์žˆ์–ด์„œ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ThreadLocal ๊ฐ’์„ ๊ฐ€์ง€๊ณ  ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

static์œผ๋กœ ์„ ์–ธํ•˜๋ฉด ํ•ด์‹œ๊ฐ’์ด ํ•ญ์ƒ ๊ฐ™๊ธฐ ๋•Œ๋ฌธ์— ํ•˜๋‚˜์˜ ThreadLocal์„ ๊ณ„์† ์“ธ ์ˆ˜ ์žˆ์–ด ์ธ์ฆ๊ฐ์ฒด๋ฅผ set ํ•œ ํ›„ ๊ณ„์†ํ•ด์„œ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋งŒ์•ฝ static์„ ์„ ์–ธํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด getContext ๋ฅผ ์„ ์–ธํ•  ๋•Œ๋งˆ๋‹ค ๊ณ„์† TheadLocal์„ ์ƒ์„ฑํ•ด์„œ ๋‹ค๋ฅธ ๋ฉ”์„œ๋“œ์—์„œ SecurityContext๋ฅผ ์‚ฌ์šฉํ• ๋•Œ ์˜ฌ๋ฐ”๋ฅด์ง€ ๋ชปํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฐธ์กฐํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์•„๋ž˜ ThreadLocalSecurityContextH ํด๋ž˜์Šค๋ฅผ ํ™•์ธํ•ด ๋ณด๋ฉด ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ThreadLocalSecurityContextHolderStrategy ThreadLocalSecurityContextHolderStrategy
  • ThreadLocal ThreadLocal

๋˜ Spring Docs์— ๋ณด๋ฉด ์ด๋Ÿฐ ๋ง์ด ์žˆ์Šต๋‹ˆ๋‹ค.

Using a ThreadLocal in this way is quite safe if care is taken to clear the thread after the present principalโ€™s request is processed. Spring Securityโ€™s FilterChainProxy ensures that the SecurityContext is always cleared.

์š”์ฒญ์ด ๋๋‚˜๋ฉด ์Šค๋ ˆ๋“œ๋ฅผ ๋น„์›Œ๋ฒ„๋ฆฐ๋‹ค๋Š” ๋‚ด์šฉ์ธ๋ฐ ์ด ๋ถ€๋ถ„๋„ ThreadLocalSecurityContextHolderStrategy ๋ฅผ ๋ณด๋ฉด ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Context๋ฅผ get์„ ํ•˜๋Š”๋ฐ ๋งŒ์•ฝ ์Šค๋ ˆ๋“œ๊ฐ€ ๋น„์–ด์žˆ์ง€ ์•Š๋Š”๋‹ค๋ฉด ์“ฐ๋ ˆ๋“œ๊ฐ€ ์žฌ์‚ฌ์šฉ๋ ๋•Œ ์“ฐ๋ ˆ๋“œ๊ฐ€ ์˜ฌ๋ฐ”๋ฅด์ง€ ์•Š์€ ๋ฐ์ดํ„ฐ๋ฅผ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ๋‹ค๋ฅธ ์ธ์ฆ์š”์ฒญ์ด ์™€๋„ ์ด๋ฏธ TheadLocal์— ์ด์ „์— ์‚ฌ์šฉ๋œ ์ธ์ฆ๊ฐ์ฒด๊ฐ€ ์žˆ์–ด์„œ ์ƒˆ๋กœ์šด ์ธ์ฆ ์š”์ฒญ์ด ์™€๋„ ์ธ์ฆ๋œ ์‚ฌ์šฉ์ž๋ผ๊ณ  ์ธ์ฆ ํ—ˆ๊ฐ€๋ฅผ ๋‚ด์ค„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

ํ—ท๊ฐˆ๋ ธ๋˜ ๋ถ€๋ถ„

  • SecurityContextHolder ์™€ Session

    • SecurityContextHolder ๋Š” Spring Security์˜ ์ธ๋ฉ”๋ชจ๋ฆฌ ์„ธ์…˜์ €์žฅ์†Œ ์ž…๋‹ˆ๋‹ค. ์‹œํ๋ฆฌํ‹ฐ์˜ ์„ค์ •์ค‘์— ์ธ์ฆ๊ณผ์ •์‹œ Session์„ ๋„๋Š” ์„ค์ •์ด ์žˆ์Šต๋‹ˆ๋‹ค.

      sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)

      JWT ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— Session์„ ์‚ฌ์šฉํ•  ํ•„์š”๊ฐ€ ์—†์–ด์„œ ํ•ด๋‹น ์„ค์ •ํ•ด์ฃผ์—ˆ๋Š”๋ฐ ๋””๋ฒ„๊น…์—์„œ SecurityContextHolder ๋กœ ๊ณ„์† ์ธ์ฆ๊ฐ์ฒด๋ฅผ ์ €์žฅํ•˜๊ณ  ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

      ์—ฌ๊ธฐ์„œ ์ œ๊ฐ€ ํ—ท๊ฐˆ๋ฆฐ ๊ฑฐ๋Š” ์„ธ์…˜์ด๋ž€ ๋‹จ์–ด๋ฅผ ํ˜ผ๋™ํ•˜๊ณ  ์žˆ์—ˆ๋˜ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ €๋Š” ์„ธ์…˜์ด๋ผ ํ•จ์€ HttpSession ์„ ๋งํ•˜๋Š” ์ค„ ์•Œ์•˜๊ฑฐ๋“ ์š”. ๊ทธ๋ž˜์„œ SecurityContextHolder ์ธ ์ธ๋ฉ”๋ชจ๋ฆฌ ์„ธ์…˜์„ ๊ณ„์† ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋„ˆ๋ฌด ์ด์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. ์ง€๊ธˆ ์ƒ๊ฐํ•˜๋ฉด ์ •๋ง ๋ฐ”๋ณด ๊ฐ™์€ ์ƒ๊ฐ์ด์ฃ 

      ๋ถ€๋„๋Ÿฝ์ง€๋งŒ, ์ €์™€ ๊ฐ™์€ ์ƒ๊ฐ์„ ํ•˜๋Š” ์‚ฌ๋žŒ์ด ์žˆ์„ ์ˆ˜ ์žˆ๊ธฐ์—.. ๊ธฐ๋ก์— ๋‚จ๊น๋‹ˆ๋‹ค.

      ์ข€ ์ž์„ธํžˆ ๋“ค์–ด๊ฐ€ ๋ณด์ž๋ฉด ์šฐ๋ฆฌ๊ฐ€ ํ”ํžˆ ์›น ํ™˜๊ฒฝ์—์„œ ์“ฐ๋Š” Session์€ HttpSession์„ ์ด์•ผ๊ธฐํ•ฉ๋‹ˆ๋‹ค. ํ†ฐ์บฃ์„ ์˜ˆ๋กœ ๋“ค๋ฉด ํ†ฐ์บฃ์—์„œ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ์ฒด ๋ฒ”์œ„์˜ ์ข…๋ฅ˜(application, session, request, page) ์ค‘ ํ•˜๋‚˜์ธ session์ด๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Spring Security์—์„œ๋Š” ํ†ฐ์บฃ์˜ ๊ฐ์ฒด ๋ฒ”์œ„(scope) ์ค‘ ํ•˜๋‚˜์ธ session์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ Threadlocal์ด๋ผ๋Š” ๊ฐ์ฒด ๋ฒ”์œ„(scope)๋ฅผ ํ™œ์šฉํ•ฉ๋‹ˆ๋‹ค.

      Session์ด๋ผ๋Š” ๊ฐœ๋…์ด ์ž˜ ์•ˆ ์žกํ˜”๊ธฐ ๋•Œ๋ฌธ์— ๋‚˜์˜จ ๋ฌธ์ œ์ด์ฃ .

      Session ์ด๋ž€ ๋‘ ๊ฐœ ๋˜๋Š” ๊ทธ ์ด์ƒ์˜ ์˜์‚ฌ์†Œํ†ตํ•˜๋Š” ์žฅ์น˜๋“ค(devices) ๋˜๋Š” ์ปดํ“จํ„ฐ ๊ทธ๋ฆฌ๊ณ  ์œ ์ € ๊ฐ„์— ๋Œ€ํ™”, ํšŒํ™” ๋˜๋Š” ํšŒ์˜์™€ ๊ฐ™์€ ๋ฐ˜์˜๊ตฌ์ ์ธ ์Œ๋ฐฉํ–ฅ ์ •๋ณด ๊ตํ™˜์ž…๋‹ˆ๋‹ค. Session์€ ์ •๋ณด๊ตํ™˜์ด๋ผ๋Š” ์˜๋ฏธ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฒƒ์ด์ง€ HttpSession์ด๋ผ๋Š” ํŠน์ •ํ•œ ๊ฒƒ์„ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ๋Š” ๊ฒ๋‹ˆ๋‹ค.

      ์ด ์ฐจ์ด๋ฅผ ์•Œ๊ฒŒ ๋˜๋‹ˆ ํ™•์‹คํžˆ ์ดํ•ด๋˜๋”๋ผ๊ณ ์š”. ํ•ด๋‹น ๋‚ด์šฉ์„ ์ž˜ ์ธ์ง€ํ•˜๊ณ  ๋“ค์–ด๊ฐ€๋ฉด ๋” ๋น ๋ฅธ ์ดํ•ด๋ฅผ ํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

      Security ๊ฐ€ ์™œ HttpSession์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ThreadLocal ์„ ์‚ฌ์šฉํ–ˆ๋Š”์ง€์— ๋Œ€ํ•ด ๋ช‡๊ฐ€์ง€ ์ด์œ ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

      1. HttpSession์€ ์„œ๋ธ”๋ฆฟ์„ ์˜์กด์ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. Security๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์„œ๋ธ”๋ฆฟ ํ•„ํ„ฐ๋ฅผ ์ด์šฉํ•ด ์„œ๋ธ”๋ฆฟ ๋ณด์•ˆ์„ ๊ธฐ๋ณธ์œผ๋กœํ•˜์ง€๋งŒ ์„œ๋ธ”๋ฆฟ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์•„๋‹Œ ์ž๋ฐ” ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์—๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค์–ด์กŒ์Šต๋‹ˆ๋‹ค.
      2. HttpSession์— ์ €์žฅํ•˜์ง€ ์•Š๊ณ  ์™ธ๋ถ€๋กœ ์ธ์ฆ์ •๋ณด๋ฅผ ์ €์žฅํ•˜๋Š” ํ˜•ํƒœ๋กœ ๊ตฌํ˜„์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.(๊ธฐ๋ณธ ํด๋ž˜์Šค๋ฅผ ํ™•์žฅํ•˜์—ฌ DB ๋˜๋Š” Redis,MongoDB ๋“ฑ์œผ๋กœ ์ธ์ฆ ์ •๋ณด๋ฅผ ์ €์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.)
      3. AOP ๋ฐ ์ธํ„ฐ์…‰ํ„ฐ ๋“ฑ ๊ณต๋™ํ”„๋ ˆ์ž„ ์›Œํฌ๋ฅผ ๋งŒ๋“ค ์‹œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

      2,3์— ๋Œ€ํ•œ ์ด์œ ๋Š” ์•„์ง ํ™•์‹คํ•˜๊ฒŒ ์™€๋‹ฟ์ง€ ์•Š์ง€๋งŒ 1์˜ ์ด์œ ๋งŒ์œผ๋กœ ์ดํ•ดํ•˜๊ธฐ์—๋Š” ์ถฉ๋ถ„ํ•˜๋‹ค๊ณ  ๋ด…๋‹ˆ๋‹ค!

  • ์ฐธ๊ณ