๐ŸŒˆ [Section4] 4. [ Spring Security ] JWT ์ธ์ฆ

ํ˜„์ฃผยท2022๋…„ 11์›” 23์ผ
0

bootcamp

๋ชฉ๋ก ๋ณด๊ธฐ
58/71

๐Ÿ“• ์˜ค๋Š˜ ๋ฐฐ์šด ๋‚ด์šฉ!

  • ์„ธ์…˜ ๊ธฐ๋ฐ˜ ์ธ์ฆ vs ํ† ํฐ ๊ธฐ๋ฐ˜ ์ธ์ฆ
  • JWT

โœ๏ธ ์„ธ์…˜ ๊ธฐ๋ฐ˜ ์ธ์ฆ

  • ์„œ๋ฒ„ or DB์— ์ธ์ฆ๋œ ์‚ฌ์šฉ์ž์˜ ์ •๋ณด๋ฅผ ์„ธ์…˜ ํ˜•ํƒœ๋กœ ์„ธ์…˜ ์ €์žฅ์†Œ์— ์ €์žฅ ํ•˜๋Š” ๋ฐฉ์‹

  • ์ธ์ฆ๋œ ์‚ฌ์šฉ์ž์˜ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ์ „ํ†ต์ ์ธ ๋ฐฉ์‹
    ( ์‚ฌ์šฉ์ž์˜ ๊ณ ์œ  ์„ธ์…˜ ID๊ฐ€ ํด๋ผ์ด์–ธํŠธ์˜ ์ฟ ํ‚ค์— ์ €์žฅ๋˜์–ด ์ธ์ฆ ์ˆ˜๋‹จ์œผ๋กœ ์‚ฌ์šฉ )

  • ์ƒ๋Œ€์ ์œผ๋กœ ์ ์€ ๋„คํŠธ์›Œํฌ ํŠธ๋ž˜ํ”ฝ ์‚ฌ์šฉ
    ( ์„ธ์…˜ ID๋งŒ ํด๋ผ์ด์–ธํŠธ ์ชฝ์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ )

  • ๋ณด์•ˆ์„ฑ ์ธก๋ฉด์—์„œ ์กฐ๊ธˆ ๋” ์œ ๋ฆฌ
    ( ์„œ๋ฒ„ ์ธก์—์„œ ์„ธ์…˜ ์ •๋ณด๋ฅผ ๊ด€๋ฆฌํ•˜๊ธฐ ๋•Œ๋ฌธ )

  • ์„œ๋ฒ„์˜ ํ™•์žฅ์„ฑ ๋ฉด์—์„œ๋Š” ์„ธ์…˜ ๋ถˆ์ผ์น˜ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์Œ
    ( ์ธ์ฆ๋œ ์‚ฌ์šฉ์ž request์˜ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•ด์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ )
    โžœ Sticky Session, Session Clustering, Session ์ €์žฅ์†Œ์˜ ์™ธ๋ถ€ ๋ถ„๋ฆฌ ๋“ฑ์˜ ์ž‘์—…์„ ํ†ตํ•ด ๋ณด์™„

    Sticky Session๊ณผ Session Clustering ์ฐธ๊ณ 
    Sticky Session ์ฐธ๊ณ 
    Session Clustering ์ฐธ๊ณ  1
    Session Clustering ์ฐธ๊ณ  2

  • ์„ธ์…˜ ๋ฐ์ดํ„ฐ๊ฐ€ ๋งŽ์•„์งˆ์ˆ˜๋ก ์„œ๋ฒ„์˜ ๋ถ€๋‹ด์ด ๊ฐ€์ค‘

  • SSR(Server Side Rendering) ๋ฐฉ์‹์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์ ํ•ฉํ•œ ๋ฐฉ์‹

โ— HTTP ํ”„๋กœํ† ์ฝœ์˜ ํŠน์ง•์ธ ๋น„์—ฐ๊ฒฐ์„ฑ(Connectionless) / ๋น„์ƒํƒœ์„ฑ(Stateless)์„ ๋ณด์™„ํ•˜์—ฌ, ์ธ์ฆ๋œ ์‚ฌ์šฉ์ž์˜ request์˜ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ์ˆ˜๋‹จ์ด ์„ธ์…˜

โœ” ์„ธ์…˜ ๊ธฐ๋ฐ˜ ์ธ์ฆ ์ ˆ์ฐจ

โœ๏ธ ํ† ํฐ ๊ธฐ๋ฐ˜ ์ธ์ฆ

  • ํ† ํฐ์— ํฌํ•จ๋œ ์ธ์ฆ๋œ ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ์„œ๋ฒ„ ์ธก์—์„œ ๋ณ„๋„๋กœ ๊ด€๋ฆฌ X

  • ์‚ฌ์šฉ์ž ์ธ์ฆ ์ •๋ณด๊ฐ€ ํฌํ•จ๋œ ํ† ํฐ์„ ํ—ค๋”์— ํฌํ•จ์‹œ์ผœ์„œ, request ์ „์†ก ์‹œ ์ธ์ฆ ์ˆ˜๋‹จ์œผ๋กœ ์‚ฌ์šฉ

  • ์„ธ์…˜์— ๋น„ํ•ด ์ƒ๋Œ€์ ์œผ๋กœ ๋งŽ์€ ๋„คํŠธ์›Œํฌ ํŠธ๋ž˜ํ”ฝ ์‚ฌ์šฉ
    ( ํ† ํฐ ๋‚ด์— ์ธ์ฆ๋œ ์‚ฌ์šฉ์ž ์ •๋ณด ๋“ฑ์„ ํฌํ•จํ•˜๊ธฐ ๋•Œ๋ฌธ )

  • ๋ณด์•ˆ์„ฑ ์ธก๋ฉด์—์„œ ์กฐ๊ธˆ ๋” ๋ถˆ๋ฆฌ
    ( ์„œ๋ฒ„ ์ธก์—์„œ ํ† ํฐ์„ ๊ด€๋ฆฌํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ )

  • ์„œ๋ฒ„์˜ ํ™•์žฅ์„ฑ ๋ฉด์—์„œ ์œ ๋ฆฌํ•˜๊ณ , ์„ธ์…˜ ๋ถˆ์ผ์น˜ ๊ฐ™์€ ๋ฌธ์ œ ๋ฐœ์ƒ X
    ( ์ธ์ฆ๋œ ์‚ฌ์šฉ์ž request์˜ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•  ํ•„์š”๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ )

  • ๋ฏผ๊ฐํ•œ ์ •๋ณด๋Š” ํ† ํฐ์— ํฌํ•จ์‹œํ‚ค์ง€ ๋ง์•„์•ผ ํ•จ
    ( ํ† ํฐ์— ํฌํ•จ๋˜๋Š” ์‚ฌ์šฉ์ž ์ •๋ณด๋Š” ํ† ํฐ ํŠน์„ฑ์ƒ ์•”ํ˜ธํ™” X์ด๊ธฐ ๋•Œ๋ฌธ )

  • ํ† ํฐ์ด ๋งŒ๋ฃŒ๋˜๊ธฐ ์ „๊นŒ์ง€๋Š” ๋ฌดํšจํ™” X
    โžœ key/value ์Œ์˜ ํ˜•ํƒœ๋กœ ์ €์žฅ๋˜๋Š” Redis ๊ฐ™์€ ์ธ๋ฉ”๋ชจ๋ฆฌ DB์— ๋ฌดํšจํ™” ์‹œํ‚ค๊ณ ์ž ํ•˜๋Š” ํ† ํฐ์˜ ๋งŒ๋ฃŒ ์‹œ๊ฐ„์„ ์งง๊ฒŒ ์ฃผ์–ด ํ•ด๋‹น ํ† ํฐ์„ ์‚ฌ์šฉํ•˜์ง€ ๋ชปํ•˜๊ฒŒ ํ•˜๋Š” ๋“ฑ์˜ ๋ฐฉ๋ฒ• ์‚ฌ์šฉํ•˜์—ฌ ๋ณด์™„

  • CSR(Client Side Rendering) ๋ฐฉ์‹์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์ ํ•ฉํ•œ ๋ฐฉ์‹

โœ” ํ† ํฐ ๊ธฐ๋ฐ˜ ์ธ์ฆ ์ ˆ์ฐจ


Ex. ๋กœ๊ทธ์ธ ์š”์ฒญ์„ ๊ฐ€์ •ํ•˜๋ฉด,

โ‘  ํด๋ผ์ด์–ธํŠธ โžœ ์„œ๋ฒ„
๐Ÿ‘‰ Username/Password ๋‹ด์•„ ๋กœ๊ทธ์ธ ์š”์ฒญ

โ‘ก ์„œ๋ฒ„ - DB
๐Ÿ‘‰ Username/Password ๊ฐ€ ์ผ์น˜ํ•˜๋Š”์ง€ ํ™•์ธ
โ €
๐Ÿ‘‰ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ๋ณด๋‚ผ ์•”ํ˜ธํ™” ๋œ ํ† ํฐ ์ƒ์„ฑ

  • Access Token / Refresh Token ๋ชจ๋‘ ์ƒ์„ฑ

  • ํ† ํฐ์— ๋‹ด๊ธธ ์ •๋ณด(Payload)๋Š” ์‚ฌ์šฉ์ž๋ฅผ ์‹๋ณ„ํ•  ์ •๋ณด, ์‚ฌ์šฉ์ž์˜ ๊ถŒํ•œ ์ •๋ณด ๋“ฑ

  • Refresh Token์„ ์ด์šฉํ•ด ์ƒˆ๋กœ์šด Access Token์„ ์ƒ์„ฑํ•  ๊ฒƒ์ด๋ฏ€๋กœ ๋‘ ์ข…๋ฅ˜์˜ ํ† ํฐ์ด ๊ฐ™์€ ์ •๋ณด๋ฅผ ๋‹ด์„ ํ•„์š”๋Š” X

โ‘ข ์„œ๋ฒ„ โžœ ํด๋ผ์ด์–ธํŠธ
๐Ÿ‘‰ ํ† ํฐ ์ „์†ก

โ‘ฃ ํด๋ผ์ด์–ธํŠธ
๐Ÿ‘‰ ํ† ํฐ ์ €์žฅ
( ์ €์žฅํ•˜๋Š” ์œ„์น˜๋Š” Local Storage, Session Storage, Cookie ๋“ฑ )

( ์ด ํ›„, ๋‹ค์Œ ์š”์ฒญ์—์„œ )

โ‘ค ํด๋ผ์ด์–ธํŠธ โžœ ์„œ๋ฒ„
๐Ÿ‘‰ HTTP Header(Authorization Header) or ์ฟ ํ‚ค์— ํ† ํฐ์„ ๋‹ด์•„ request ์ „์†ก
( Bearer authentication ์ด์šฉ )

[Bearer authentication ์ฐธ๊ณ ]
์š”์•ฝ - https://learning.postman.com/docs/sending-requests/authorization/#bearer-token
์ƒ์„ธ - https://www.rfc-editor.org/rfc/rfc6750

โ‘ฅ ์„œ๋ฒ„
๐Ÿ‘‰ ํ† ํฐ ๊ฒ€์ฆ ํ›„, ์ผ์น˜ํ•  ๊ฒฝ์šฐ ์š”์ฒญ ์ฒ˜๋ฆฌ ํ›„ ์‘๋‹ต
( ์„œ๋ฒ„๊ฐ€ ๋ฐœ๊ธ‰ํ–ˆ๋˜ ํ† ํฐ์ด ๋งž์„ ๊ฒฝ์šฐ, ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ์„ ์ฒ˜๋ฆฌ ํ›„ ์‘๋‹ต ๋ณด๋ƒ„ )


โœ๏ธ JWT (Json Web Token)

JWT ๊ณต์‹ ์‚ฌ์ดํŠธ

  • Json ํฌ๋งท์œผ๋กœ ์‚ฌ์šฉ์ž์— ๋Œ€ํ•œ ์†์„ฑ์„ ์ €์žฅํ•˜๋Š” ์›น ํ† ํฐ

  • ๋ฐ์ดํ„ฐ๋ฅผ ์•ˆ์ „ํ•˜๊ณ  ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์ „์†กํ•˜๊ธฐ ์œ„ํ•ด ๊ณ ์•ˆ๋œ ์ธํ„ฐ๋„ท ํ‘œ์ค€ ์ธ์ฆ ๋ฐฉ์‹

  • ํ† ํฐ ์ธ์ฆ ๋ฐฉ์‹์—์„œ ๊ฐ€์žฅ ๋ฒ”์šฉ์ ์œผ๋กœ ์‚ฌ์šฉ

  • JSON ํฌ๋งท์˜ ํ† ํฐ ์ •๋ณด๋ฅผ ์ธ์ฝ”๋”ฉ ํ›„, ์ธ์ฝ”๋”ฉ ๋œ ํ† ํฐ ์ •๋ณด๋ฅผ Secret Key๋กœ ์„œ๋ช…(Sign)ํ•œ ๋ฉ”์‹œ์ง€๋ฅผ Web Token์œผ๋กœ์จ ์ธ์ฆ ๊ณผ์ •์— ์‚ฌ์šฉ

[์ฐธ๊ณ ] https://jwt.io/introduction

โœ” JWT ์ข…๋ฅ˜

โœ”๏ธ ์•ก์„ธ์Šค ํ† ํฐ (Access Token)

  • ๋ณดํ˜ธ๋œ ์ •๋ณด๋“ค(์‚ฌ์šฉ์ž์˜ ์ด๋ฉ”์ผ, ์—ฐ๋ฝ์ฒ˜, ์‚ฌ์ง„ ๋“ฑ)์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๊ถŒํ•œ๋ถ€์—ฌ์— ์‚ฌ์šฉ

  • ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ฒ˜์Œ ์ธ์ฆ์„ ๋ฐ›๊ฒŒ ๋  ๋•Œ(๋กœ๊ทธ์ธ ์‹œ), Access Token๊ณผ Refresh Token ๋‘ ๊ฐ€์ง€๋ฅผ ๋‹ค ๋ฐ›์ง€๋งŒ, ์‹ค์ œ๋กœ ๊ถŒํ•œ์„ ์–ป๋Š” ๋ฐ ์‚ฌ์šฉํ•˜๋Š” ํ† ํฐ์€ Access Token

  • ํƒˆ์ทจ๋˜๋”๋ผ๋„ ์˜ค๋žซ๋™์•ˆ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋„๋ก ๋น„๊ต์  ์งง์€ ์œ ํšจ๊ธฐ๊ฐ„
    โžœ ์œ ํšจ๊ธฐ๊ฐ„์ด ๋งŒ๋ฃŒ๋œ๋‹ค๋ฉด Refresh Token์„ ์‚ฌ์šฉํ•˜์—ฌ ์ƒˆ๋กœ์šด Access Token์„ ๋ฐœ๊ธ‰๋ฐ›์Œ
    ( ๋‹ค์‹œ ๋กœ๊ทธ์ธ ์ธ์ฆ ํ•„์š” X )

โœ”๏ธ ๋ฆฌํ”„๋ ˆ์‹œ ํ† ํฐ (Refresh Token)

  • Access Token ๋ฐœ๊ธ‰๋ฐ›์„ ๋•Œ ์‚ฌ์šฉ

  • ๊ธด ์œ ํšจ๊ธฐ๊ฐ„
    โžœ But, ์œ ํšจ๊ธฐ๊ฐ„์ด ๊ธธ์–ด ํƒˆ์ทจ๋‹นํ•œ๋‹ค๋ฉด ํฐ ํ”ผํ•ด๊ฐ€ ์˜ฌ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—,
    ์‚ฌ์šฉ์ž์˜ ํŽธ์˜๋ณด๋‹ค ์ •๋ณด๋ฅผ ์ง€ํ‚ค๋Š” ๊ฒƒ์ด ๋” ์ค‘์š”ํ•œ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ Refresh Token์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ณณ์ด ๋งŽ์Œ

Refresh Token ๋ฐœ๊ธ‰ ๊ธฐ๊ฐ„ ์ฐธ๊ณ 

โ— ์„ธ์ƒ์— ์™„๋ฒฝํ•œ ๋ณด์•ˆ์€ ์—†์œผ๋ฏ€๋กœ ๊ฐ ์žฅ๋‹จ์ ์„ ์ฐธ๊ณ ํ•˜์—ฌ ํ•„์š”์— ๋งž๊ฒŒ ์‚ฌ์šฉํ•˜๊ธฐ

โœ” JWT ๊ตฌ์กฐ

( . ์„ ๊ธฐ์ค€์œผ๋กœ Header / Payload / Signature ์„ธ ๋ถ€๋ถ„์œผ๋กœ ๋‚˜๋‰จ )

โœ”๏ธ Header

  • ์–ด๋–ค ์ข…๋ฅ˜์˜ ํ† ํฐ์ธ์ง€(์ง€๊ธˆ์˜ ๊ฒฝ์šฐ์—” JWT), ์–ด๋–ค ์•Œ๊ณ ๋ฆฌ์ฆ˜์œผ๋กœ ์•”ํ˜ธํ™”ํ• ์ง€ ์ •์˜
    ( JSON ํฌ๋งท ํ˜•ํƒœ๋กœ ์ •์˜ )

  • JSON ๊ฐ์ฒด๋ฅผ base64 ๋ฐฉ์‹์œผ๋กœ ์ธ์ฝ”๋”ฉํ•˜๋ฉด JWT์˜ ์ฒซ ๋ฒˆ์งธ ๋ถ€๋ถ„์ด ์™„์„ฑ

โœ”๏ธ Payload

  • ์„œ๋ฒ„์—์„œ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์‚ฌ์šฉ์ž์˜ ์ •๋ณด๊ฐ€ ๋‹ด๊ฒจ์žˆ์Œ
    Ex. ์ ‘๊ทผ ๊ถŒํ•œ / ์‚ฌ์šฉ์ž ๋ฐ์ดํ„ฐ ๋“ฑ

  • ๋ฏผ๊ฐํ•œ ์ •๋ณด๋Š” ๋‹ด์ง€ ์•Š๋Š” ๊ฒƒ์ด ์ข‹์Œ
    Ex. password

  • JSON ๊ฐ์ฒด๋ฅผ base64 ๋ฐฉ์‹์œผ๋กœ ์ธ์ฝ”๋”ฉํ•˜๋ฉด JWT์˜ ๋‘ ๋ฒˆ์งธ ๋ถ€๋ถ„์ด ์™„์„ฑ

โœ”๏ธ Signature
( base64๋กœ ์ธ์ฝ”๋”ฉ๋œ ์ฒซ ๋ฒˆ์งธ, ๊ทธ๋ฆฌ๊ณ  ๋‘ ๋ฒˆ์งธ ๋ถ€๋ถ„์ด ์™„์„ฑ๋˜์—ˆ๋‹ค๋ฉด, )

  • ์›ํ•˜๋Š” ๋น„๋ฐ€ ํ‚ค(Secret Key) + Header์—์„œ ์ง€์ •ํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‚ฌ์šฉํ•˜์—ฌ Header์™€ Payload์— ๋Œ€ํ•ด์„œ ๋‹จ๋ฐฉํ–ฅ ์•”ํ˜ธํ™” ์ˆ˜ํ–‰
    โ €
    โžœ ์•”ํ˜ธํ™” ๋œ ๋ฉ”์‹œ์ง€๋Š” ํ† ํฐ์˜ ์œ„๋ณ€์กฐ ์œ ๋ฌด๋ฅผ ๊ฒ€์ฆํ•˜๋Š”๋ฐ ์‚ฌ์šฉ

    Ex. HMAC SHA256 ์•Œ๊ณ ๋ฆฌ์ฆ˜(์•”ํ˜ธํ™” ๋ฐฉ๋ฒ• ์ค‘ ํ•˜๋‚˜) ์‚ฌ์šฉํ•œ๋‹ค๋ฉด,
    HMACSHA256(base64UrlEncode(header) + '.' + base64UrlEncode(payload), secret);
    ์ด์™€ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ Signature๊ฐ€ ์ƒ์„ฑ๋จ

โœ” JWT ์ธ์ฆ์˜ ์žฅ์ 

  • ๋ฌด์ƒํƒœ์„ฑ (Statelessness) & ํ™•์žฅ์„ฑ (Scalability)

    • ํด๋ผ์ด์–ธํŠธ์— ๋Œ€ํ•œ ์ •๋ณด ์ €์žฅํ•  ํ•„์š” X / ํ† ํฐ์ด ์ •์ƒ์ ์œผ๋กœ ๊ฒ€์ฆ๋˜๋Š”์ง€๋งŒ ํŒ๋‹จ
      โžœ ์„œ๋ฒ„์™€ DB์˜ ๋ถ€๋‹ด ๋œ์–ด์คŒ

    • ํด๋ผ์ด์–ธํŠธ๊ฐ€ request ์ „์†กํ•  ๋•Œ ๋งˆ๋‹ค ํ—ค๋”์— ํ† ํฐ์„ ํฌํ•จ์‹œ์ผœ ์ „์†ก
      โžœ ํ•˜๋‚˜์˜ ํ† ํฐ์œผ๋กœ ์—ฌ๋Ÿฌ ์„œ๋ฒ„์— ์ธ์ฆ ๊ฐ€๋Šฅ
      ( ์„ธ์…˜ ๋ฐฉ์‹์ด๋ผ๋ฉด ๋ชจ๋“  ์„œ๋ฒ„๊ฐ€ ํ•ด๋‹น ์‚ฌ์šฉ์ž์˜ ์„ธ์…˜ ์ •๋ณด๋ฅผ ๊ณต์œ ํ•˜๊ณ  ์žˆ์–ด์•ผ ํ•จ )

  • ํด๋ผ์ด์–ธํŠธ๊ฐ€ request๋ฅผ ์ „์†กํ•  ๋•Œ ๋งˆ๋‹ค ์ธ์ฆ ์ •๋ณด ์ „์†กํ•  ํ•„์š” ์—†์Œ

    • ํ† ํฐ์ด ๋งŒ๋ฃŒ๋˜๊ธฐ ์ „๊นŒ์ง€๋Š” ์ธ์ฆ์€ ํ•œ๋ฒˆ๋งŒ ์ˆ˜ํ–‰
      ( HTTP Basic ๊ฐ™์€ ์ธ์ฆ ๋ฐฉ์‹์€ request๋ฅผ ์ „์†กํ•  ๋•Œ ๋งˆ๋‹ค ์ธ์ฆ ์ •๋ณด๋ฅผ ํฌํ•จํ•ด์•ผํ•จ )
  • ์•ˆ์ •์„ฑ

    • ์•”ํ˜ธํ™”ํ•œ ํ† ํฐ ์‚ฌ์šฉ

    • ์•”ํ˜ธํ™” ํ‚ค๋ฅผ ๋…ธ์ถœํ•  ํ•„์š” X

  • ์–ด๋””์„œ๋‚˜ ์ƒ์„ฑ ๊ฐ€๋Šฅ

    • ํ† ํฐ์„ ์ƒ์„ฑํ•˜๋Š” ์„œ๋ฒ„๊ฐ€ ๊ผญ ๊ทธ ํ† ํฐ์„ ๋งŒ๋“ค์ง€ ์•Š์•„๋„ ๋˜๊ณ ,
      ํ† ํฐ ์ƒ์„ฑ์šฉ ์„œ๋ฒ„๋ฅผ ๋งŒ๋“ค๊ฑฐ๋‚˜, ๋‹ค๋ฅธ ํšŒ์‚ฌ์—์„œ ํ† ํฐ ๊ด€๋ จ ์ž‘์—…์„ ๋งก๊ธฐ๋Š” ๊ฒƒ ๋“ฑ ๋‹ค์–‘ํ•œ ํ™œ์šฉ ๊ฐ€๋Šฅ

    • ์‚ฌ์šฉ์ž์˜ ์ž๊ฒฉ ์ฆ๋ช… ์ •๋ณด๋ฅผ ์ง์ ‘ ๊ด€๋ฆฌํ•˜์ง€ ์•Š๊ณ , ๋‹ค๋ฅธ ํ”Œ๋žซํผ์˜ ์ž๊ฒฉ ์ฆ๋ช… ์ •๋ณด๋กœ ์ธ์ฆ ๊ฐ€๋Šฅ
      Ex. Github / Google ๋“ฑ

  • ๊ถŒํ•œ ๋ถ€์—ฌ์— ์šฉ์ด

    • ํ† ํฐ์˜ Payload ์•ˆ์— ํ•ด๋‹น ์‚ฌ์šฉ์ž์˜ ๊ถŒํ•œ ์ •๋ณด๋ฅผ ํฌํ•จํ•˜๋Š” ๊ฒƒ์ด ์šฉ์ด

โœ” JWT ์ธ์ฆ์˜ ๋‹จ์ 

  • Payload ๋””์ฝ”๋”ฉ์ด ์šฉ์ด
    โžœ ํƒˆ์ทจํ•˜์—ฌ ๋””์ฝ”๋”ฉ ํ›„ ๋ฐ์ดํ„ฐ ํ™•์ธ์ด ๊ฐ€๋Šฅํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฏผ๊ฐํ•œ ์ •๋ณด๋Š” ํฌํ•จ X

  • ํ† ํฐ์˜ ๊ธธ์ด๊ฐ€ ๊ธธ์–ด์ง€๋ฉด ๋„คํŠธ์›Œํฌ์— ๋ถ€ํ•˜๋ฅผ ์ค„ ์ˆ˜ ์žˆ์Œ
    โžœ ํ† ํฐ์— ์ €์žฅํ•˜๋Š” ์ •๋ณด์˜ ์–‘์ด ๋งŽ์•„์งˆ ์ˆ˜๋ก ํ† ํฐ์˜ ๊ธธ์ด๋Š” ๊ธธ์–ด์ง€๊ธฐ ๋•Œ๋ฌธ์—
    request ์ „์†ก ์‹œ ๋งˆ๋‹ค ๊ธด ํ† ํฐ ์ „์†กํ•˜๋ฉด ๋„คํŠธ์›Œํฌ์— ๋ถ€ํ•˜๋ฅผ ์ค„ ์ˆ˜ ์žˆ์Œ

  • ํ† ํฐ์€ ์ž๋™์œผ๋กœ ์‚ญ์ œ๋˜์ง€ ์•Š์Œ
    โžœ ๋˜, ํƒˆ์ทจ๋  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๊ธฐ์— ๋ฐ˜๋“œ์‹œ ๊ธธ์ง€ ์•Š์€ ํ† ํฐ ๋งŒ๋ฃŒ ๊ธฐ๊ฐ„ ์ถ”๊ฐ€ํ•˜๊ธฐ


โœ๏ธ JWT๋ฅผ ์ด์šฉํ•œ ๋กœ๊ทธ์ธ ์ธ์ฆ ํ๋ฆ„

( ์‚ฌ์šฉ์ž์˜ ๋กœ๊ทธ์ธ ์ธ์ฆ ์„ฑ๊ณต ํ›„, JWT๊ฐ€ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์ „๋‹ฌ๋˜๋Š” ๊ณผ์ • )

โ‘  ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์„œ๋ฒ„ ์ธก์— ๋กœ๊ทธ์ธ ์ธ์ฆ ์š”์ฒญ(Username/Password๋ฅผ ์„œ๋ฒ„ ์ธก์— ์ „์†ก)

๐Ÿ’ฌ ํด๋ผ์ด์–ธํŠธ :
์„œ๋ฒ„์•ผ, ์ด Username/Password๋กœ ๋กœ๊ทธ์ธ ์ธ์ฆ ์ข€ ํ•ด์ค˜

โ‘ก ๋กœ๊ทธ์ธ ์ธ์ฆ์„ ๋‹ด๋‹นํ•˜๋Š” Security Filter(JwtAuthenticationFilter)๊ฐ€ ํด๋ผ์ด์–ธํŠธ์˜ ๋กœ๊ทธ์ธ ์ธ์ฆ ์ •๋ณด ์ˆ˜์‹ 

๐Ÿ’ฌ Security Filter (JwtAuthenticationFilter) :
OK ๋‚ด๊ฐ€ ๋ฐ›์Œ.

โ‘ข Security Filter๊ฐ€ ์ˆ˜์‹ ํ•œ ๋กœ๊ทธ์ธ ์ธ์ฆ ์ •๋ณด๋ฅผ AuthenticationManager์—๊ฒŒ ์ „๋‹ฌํ•ด ์ธ์ฆ ์ฒ˜๋ฆฌ๋ฅผ ์œ„์ž„

๐Ÿ’ฌ Security Filter (JwtAuthenticationFilter) :
์•ผ AuthenticationManager, ๋กœ๊ทธ์ธ ์ธ์ฆ ์ •๋ณด ์ค„ํ…Œ๋‹ˆ๊นŒ ๋„ค๊ฐ€ ๋Œ€์‹  ์ธ์ฆ ์ฒ˜๋ฆฌํ•ด.

โ‘ฃ AuthenticationManager๊ฐ€ Custom UserDetailsService(MemberDetailsService)์—๊ฒŒ ์‚ฌ์šฉ์ž์˜ UserDetails ์กฐํšŒ๋ฅผ ์œ„์ž„

๐Ÿ’ฌ AuthenticationManager :
OK ๋‚ด๊ฐ€ ํ•จ.
์•ผ UserDetailsService(MemberDetailsService), ์ด ์‚ฌ์šฉ์ž UserDetails ์กฐํšŒ ํ•œ๋ฒˆ ํ•ด๋ด๋ผ.

โ‘ค Custom UserDetailsService(MemberDetailsService)๊ฐ€ ์‚ฌ์šฉ์ž์˜ ํฌ๋ฆฌ๋ด์…œ์„ DB์—์„œ ์กฐํšŒํ•œ ํ›„, AuthenticationManager์—๊ฒŒ ์‚ฌ์šฉ์ž์˜ UserDetails๋ฅผ ์ „๋‹ฌ

๐Ÿ’ฌ UserDetailsService (MemberDetailsService) :
OK ๋‚ด๊ฐ€ ํ•จ.
์•ผ AuthenticationManager, ๊ทธ ์‚ฌ์šฉ์ž ํฌ๋ฆฌ๋ด์…œ ์กฐํšŒํ•ด๋ดค๋”๋‹ˆ ์ด UserDetails ๋‚˜์™”์–ด.
๋„ˆ ์ค„๊ฒŒ.

โ‘ฅ AuthenticationManager๊ฐ€ ๋กœ๊ทธ์ธ ์ธ์ฆ ์ •๋ณด์™€ UserDetails์˜ ์ •๋ณด๋ฅผ ๋น„๊ตํ•ด ์ธ์ฆ ์ฒ˜๋ฆฌ

๐Ÿ’ฌ AuthenticationManager :
OK ๋ฐ›์Œ.
๊ทธ๋Ÿผ ๋‚ด๊ฐ€ ์•„๊นŒ Security Filter(JwtAuthenticationFilter)๊ฐ€ ์ค€ ๋กœ๊ทธ์ธ ์ธ์ฆ ์ •๋ณด๋ž‘ ๋„ค๊ฐ€ ์ค€ UserDetails๋ž‘ ๋น„๊ตํ•ด์„œ ๊ฐ™์€ ์‚ฌ์šฉ์ž์ธ์ง€ ๋ณผ๊ฒŒ.

โ‘ฆ JWT ์ƒ์„ฑ ํ›„, ํด๋ผ์ด์–ธํŠธ์˜ ์‘๋‹ต์œผ๋กœ ์ „๋‹ฌ

๐Ÿ’ฌ AuthenticationManager :
๊ฐ™์€ ์‚ฌ์šฉ์ž์ธ ๊ฑฐ ์ธ์ฆ ๋์œผ๋‹ˆ๊นŒ JWT ์ƒ์„ฑํ•ด์„œ ์‘๋‹ต์œผ๋กœ ์ค„๊ฒŒ.

โ— ์šฐ๋ฆฌ๋Š” ์—ฌ๊ธฐ์„œ
JwtAuthenticationFilter(โ‘ก,โ‘ข,โ‘ฆ) / MemberDetailsService(โ‘ค) ๊ตฌํ˜„
( โ‘ฃ,โ‘ฅ์€ Spring Security์˜ AuthenticationManager๊ฐ€ ๋Œ€์‹  ์ฒ˜๋ฆฌํ•ด ์คŒ )


๐Ÿ˜œ ์‹ค์Šต

  • projects - be-template-spring-security-jwt-basic

โœ” JWT ์ž๊ฒฉ ์ฆ๋ช…์„ ์œ„ํ•œ ์‚ฌ์ „ ์ž‘์—…

  1. ์˜์กด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ถ”๊ฐ€

    implementation 'org.springframework.boot:spring-boot-starter-security' // (1) Spring Security ์ ์šฉํ•˜๊ธฐ ์œ„ํ•ด
    โ €โ €
    // (2) JWT ๊ธฐ๋Šฅ์„ ์œ„ํ•œ jjwt ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ( Spring Security ๊ธฐ๋ฐ˜์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— JWT ์ ์šฉํ•˜๊ธฐ ์œ„ํ•ด )
    implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
    runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5'
    runtimeOnly	'io.jsonwebtoken:jjwt-jackson:0.11.5'

    โ— JWT๋ฅผ ์ ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” jjwt๋‚˜ Java JWT ๊ฐ™์€ ๋ณ„๋„์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ํ•„์š”
    jjwt ์ฐธ๊ณ 
    java-jwt ์ฐธ๊ณ 

  2. SecurityConfigurationV1 ํด๋ž˜์Šค ์ถ”๊ฐ€
    CORS ์ฐธ๊ณ  1
    CORS ์ฐธ๊ณ  2

  3. ํšŒ์› ๊ฐ€์ž… ๋กœ์ง ์ˆ˜์ •

    3-1. MemberDto.Post ํด๋ž˜์Šค์— ํŒจ์Šค์›Œ๋“œ ํ•„๋“œ ์ถ”๊ฐ€

    3-2. Member ์—”ํ‹ฐํ‹ฐ ํด๋ž˜์Šค์— ํŒจ์Šค์›Œ๋“œ ํ•„๋“œ ์ถ”๊ฐ€

    3-3. MemberService ํด๋ž˜์Šค์— ์‚ฌ์šฉ์ž ๋“ฑ๋ก ์‹œ, ํŒจ์Šค์›Œ๋“œ์™€ ์‚ฌ์šฉ์ž ๊ถŒํ•œ ์ €์žฅ

    3-4. CustomAuthorityUtils ํด๋ž˜์Šค ์ถ”๊ฐ€
    โžœ MemberService ํด๋ž˜์Šค์— DI ํ•˜๊ธฐ ์œ„ํ•จ

โœ” JWT ์ž๊ฒฉ ์ฆ๋ช…์„ ์œ„ํ•œ ๋กœ๊ทธ์ธ ์ธ์ฆ ๊ตฌํ˜„

โ— ํ•ต์‹ฌ
โžœ ์‚ฌ์šฉ์ž์˜ Username(์ด๋ฉ”์ผ ์ฃผ์†Œ)๊ณผ Password ๋กœ ๋กœ๊ทธ์ธ ์ธ์ฆ์— ์„ฑ๊ณตํ•˜๋ฉด,
๋กœ๊ทธ์ธ ์ธ์ฆ์— ์„ฑ๊ณตํ•œ ์‚ฌ์šฉ์ž์—๊ฒŒ JWT ๋ฅผ ์ƒ์„ฑ ๋ฐ ๋ฐœ๊ธ‰ํ•˜๋Š” ๊ฒƒ

  1. MemberDetailsService ํด๋ž˜์Šค ์ถ”๊ฐ€
    โžœ Custom UserDetailsService ๊ตฌํ˜„

  2. LoginDto ํด๋ž˜์Šค ์ถ”๊ฐ€
    โžœ ํด๋ผ์ด์–ธํŠธ์˜ Username + Password ์ •๋ณด๋งŒ ๋‹ด๋Š” ๋‹จ์ˆœํ•œ DTO ํด๋ž˜์Šค
    โžœ ๋กœ๊ทธ์ธ ์ธ์ฆ ์ •๋ณด ์—ญ์ง๋ ฌํ™”(Deserialization)๋ฅผ ์œ„ํ•จ

  3. JwtTokenizer ํด๋ž˜์Šค ์ถ”๊ฐ€
    โžœ JWT ์ƒ์„ฑ

  4. JwtAuthenticationFilter ํด๋ž˜์Šค ์ถ”๊ฐ€ ( Custom Security Filter )
    โžœ ๋กœ๊ทธ์ธ ์ธ์ฆ ์š”์ฒญ ์ฒ˜๋ฆฌ

  5. SecurityConfigurationV2 ํด๋ž˜์Šค์— ์„ค์ • ์ถ”๊ฐ€
    โžœ Custom Filter ์ถ”๊ฐ€๋ฅผ ์œ„ํ•ด
    โžœ JwtAuthenticationFilter ๋ฅผ Spring Security Filter Chain ์— ์ถ”๊ฐ€ํ•ด์„œ ๋กœ๊ทธ์ธ ์ธ์ฆ์„ ์ฒ˜๋ฆฌํ•˜๋„๋ก

๐Ÿ”Š ์ด ํ›„, postman์œผ๋กœ member ๋“ฑ๋ก ํ›„,
/v11/auth/login ๊ฒฝ๋กœ๋กœ username / password postํ•˜๋ฉด ๋กœ๊ทธ์ธ์ด ์ธ์ฆ๋˜์–ด
Headers ํƒญ์—์„œ Authorization ํ‚ค์˜ ๊ฐ’์œผ๋กœ Access Token,
Refresh ํ‚ค์˜ ๊ฐ’์œผ๋กœ Refresh Token ํฌํ•จ๋˜์–ด ๋‚˜ํƒ€๋‚จ
โ €
โžœ ํด๋ผ์ด์–ธํŠธ ์ชฝ์—์„œ ์„œ๋ฒ„ ์ธก์˜ ๋ฆฌ์†Œ์Šค๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ request ์ „์†กํ•  ๋•Œ ๋งˆ๋‹ค
์ „๋‹ฌ ๋ฐ›์€ JWT ๋ฅผ request header ์— ํฌํ•จ ํ›„,
ํด๋ผ์ด์–ธํŠธ์˜ ์ž๊ฒฉ ์ฆ๋ช… ์ •๋ณด๋กœ ์‚ฌ์šฉํ•˜๋ฉด ๋จ !

โœ” ๋กœ๊ทธ์ธ ์ธ์ฆ ์„ฑ๊ณต ๋ฐ ์‹คํŒจ์— ๋”ฐ๋ฅธ ์ถ”๊ฐ€ ์ฒ˜๋ฆฌ

  1. AuthenticationSuccessHandler ํด๋ž˜์Šค ์ถ”๊ฐ€
    โžœ ๋กœ๊ทธ๋ฅผ ๊ธฐ๋ก or ๋กœ๊ทธ์ธ์— ์„ฑ๊ณตํ•œ ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ response๋กœ ์ „์†กํ•˜๋Š” ๋“ฑ์˜ ์ถ”๊ฐ€ ์ฒ˜๋ฆฌ
    AuthenticationSuccessHandler ์ฐธ๊ณ 

  2. AuthenticationFailureHandler ํด๋ž˜์Šค ์ถ”๊ฐ€
    โžœ ๋กœ๊ทธ์ธ ์ธ์ฆ ์‹คํŒจ ์‹œ์—๋„ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ธ์ฆ ์‹คํŒจ์— ๋Œ€ํ•ด ์ถ”๊ฐ€ ์ฒ˜๋ฆฌ ๊ฐ€๋Šฅ
    AuthenticationFailureHandler ์ฐธ๊ณ 

  3. SecurityConfigurationV3 ํด๋ž˜์Šค์— ์„ค์ • ์ถ”๊ฐ€
    โžœ AuthenticationSuccessHandler / AuthenticationFailureHandler ์ถ”๊ฐ€

    โ— AuthenticationSuccessHandler ์ธํ„ฐํŽ˜์ด์Šค์™€ AuthenticationFailureHandler ์ธํ„ฐํŽ˜์ด์Šค์˜ ๊ตฌํ˜„ ํด๋ž˜์Šค๋ฅผ JwtAuthenticationFilter ์— ๋“ฑ๋กํ•˜๋ฉด ๋กœ๊ทธ์ธ ์ธ์ฆ ์‹œ, ๋‘ ํ•ธ๋“ค๋Ÿฌ ์‚ฌ์šฉ ๊ฐ€๋Šฅ

  4. JwtAuthenticationFilter ํด๋ž˜์Šค์— ์„ค์ • ์ถ”๊ฐ€
    โžœ AuthenticationSuccessHandler ํ˜ธ์ถœ ์ฝ”๋“œ ์ถ”๊ฐ€

โœ” JWT ๊ฒ€์ฆ ๊ธฐ๋Šฅ ๊ตฌํ˜„

โžœ ์ž๊ฒฉ ์ฆ๋ช…์ด ํ•„์š”ํ•œ request ์ „์†ก ์‹œ, request header ๋ฅผ ํ†ตํ•ด ์ „๋‹ฌ๋ฐ›์€ JWT ๋ฅผ ์„œ๋ฒ„ ์ธก์—์„œ ๊ฒ€์ฆํ•˜๋Š” ๊ธฐ๋Šฅ ๊ตฌํ˜„

  1. JwtVerificationFilter ํด๋ž˜์Šค ์ถ”๊ฐ€
    โžœ ํด๋ผ์ด์–ธํŠธ ์ธก์—์„œ ์ „์†ก๋œ request header ์— ํฌํ•จ๋œ JWT ์˜ ๊ฒ€์ฆ ์ž‘์—… ์ˆ˜ํ–‰
    โžœ ์„œ๋ฒ„ ์ธก์—์„œ response header ์— JWT ๋ฅผ ํฌํ•จํ•ด ์ „์†กํ•œ ํ›„ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋‹ค์‹œ ์š”์ฒญ๋ณด๋‚ผ ๋•Œ,
    ๊ทธ JWT ๋ฅผ request header ์— ํฌํ•จํ•˜์—ฌ ์ „์†กํ•  ๊ฒฝ์šฐ์— ์„œ๋ฒ„๊ฐ€ ๋ณด๋‚ธ JWT ๊ฐ€ ๋งž๋Š”์ง€ ๊ฒ€์ฆํ•˜๋Š” ๊ณผ์ •์ž„
  2. SecurityConfigurationV4 ํด๋ž˜์Šค์— ์„ค์ • ์ถ”๊ฐ€
    โžœ JwtVerificationFilter๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์„ธ์…˜ ์ •์ฑ… ์„ค์ • + JwtVerification ์ถ”๊ฐ€

    โ— 1๋ฒˆ์—์„œ ๊ฒ€์ฆ ์„ฑ๊ณตํ•˜๋ฉด Authentication ๊ฐ์ฒด๋ฅผ SecurityContext์— ์ €์žฅํ•˜๋Š”๋ฐ stateless ํŠน์ง•์„ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ์„ธ์…˜ ์œ ์ง€ ๊ธฐ๊ฐ„์„ ์•„์ฃผ ์งง๊ฒŒ(๊ฑฐ์˜ ๋ฌด์ƒํƒœ) ์ฃผ๊ธฐ ์œ„ํ•ด ์„ค์ • ์ถ”๊ฐ€

  3. SecurityConfigurationV5 ํด๋ž˜์Šค ์ถ”๊ฐ€
    โžœ SecurityConfigurationV4 + ์ ‘๊ทผ ๊ถŒํ•œ ์„ค์ •

    โ— SecurityConfigurationV4 ํด๋ž˜์Šค๋Š” ์ ‘๊ทผ ๊ถŒํ•œ์ด .anyRequest().permitAll() ๋กœ ๋˜์–ด์žˆ์–ด ๋ชจ๋‘ ์ ‘๊ทผ ๊ฐ€๋Šฅ

โœ” ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ๋กœ์ง ์ถ”๊ฐ€

์ง€๊ธˆ๊นŒ์ง€๋Š” JwtVerificationFilter์—์„œ SignatureException๊ณผ ExpiredJwtException์— ๋Œ€ํ•ด ์–ด๋–ค ์ฒ˜๋ฆฌ๋„ ํ•˜์ง€ ์•Š๊ณ  ์žˆ์Œ

โœ”๏ธ SignatureException
โžœ JWT ์— ๋Œ€ํ•œ ์„œ๋ช…(Signature) ๊ฒ€์ฆ์— ์‹คํŒจํ•  ๊ฒฝ์šฐ throw๋˜๋Š” ์˜ˆ์™ธ


โœ”๏ธ ExpiredJwtException
โžœ JWT ๊ฐ€ ๋งŒ๋ฃŒ๋  ๊ฒฝ์šฐ throw๋˜๋Š” ์˜ˆ์™ธ

  1. JwtVerificationFilter ํด๋ž˜์Šค์— ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ๋กœ์ง ์ถ”๊ฐ€
    โžœ JWT ๊ฒ€์ฆ ๊ณผ์ •์—์„œ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” Exception์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก
    AuthenticationEntryPoint ์ฐธ๊ณ 

  2. MemberAuthenticationEntryPoint ํด๋ž˜์Šค ์ถ”๊ฐ€
    โžœ AuthenticationException์ด ๋ฐœ์ƒํ•  ๋•Œ ํ˜ธ์ถœ๋˜๋Š” ํ•ธ๋“ค๋Ÿฌ ๊ฐ™์€ ์—ญํ• 
    โžœ ์—ฌ๊ธฐ์„œ๋Š” AuthenticationException ๋ฐœ์ƒํ•˜๋ฉด ErrorResponse ๋ฅผ ์ƒ์„ฑํ•ด์„œ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์ „์†กํ•˜๋„๋ก ๊ตฌํ˜„

    โœ”๏ธ AuthenticationException
    โžœ ๋Œ€ํ‘œ์ ์œผ๋กœ SecurityContext ์— Authentication ์ด ์ €์žฅ๋˜์ง€ ์•Š์•˜์„ ๋•Œ ๋ฐœ์ƒํ•˜๋Š” ์—๋Ÿฌ

  3. ErrorResponse ํด๋ž˜์Šค ์ถ”๊ฐ€
    โžœ AuthenticationException ๋ฐœ์ƒํ•˜๋ฉด ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์ „์†กํ•  ํด๋ž˜์Šค

  4. MemberAccessDeniedHandler ํด๋ž˜์Šค ์ถ”๊ฐ€
    โžœ ์ธ์ฆ์—๋Š” ์„ฑ๊ณตํ–ˆ์ง€๋งŒ ํ•ด๋‹น ๋ฆฌ์†Œ์Šค์— ๋Œ€ํ•œ ๊ถŒํ•œ์ด ์—†์„ ๊ฒฝ์šฐ ํ˜ธ์ถœ๋˜๋Š” ํ•ธ๋“ค๋Ÿฌ
    AccessDeniedHandler ์ฐธ๊ณ 

  5. SecurityConfiguration ํด๋ž˜์Šค ์ถ”๊ฐ€
    โžœ MemberAuthenticationEntryPoint / MemberAccessDeniedHandler ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์ถ”๊ฐ€

โ— Username/Password ๊ธฐ๋ฐ˜์˜ ๋กœ๊ทธ์ธ ์ธ์ฆ์€ OncePerRequestFilter ๊ฐ™์€ Spring Security์—์„œ ์ง€์›ํ•˜๋Š” ๋‹ค๋ฅธ Filter ์ด์šฉํ•ด์„œ๋„ ๊ตฌํ˜„ ๊ฐ€๋Šฅํ•˜๊ณ ,
Controller์—์„œ REST API ์—”๋“œํฌ์ธํŠธ๋กœ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•จ
OncePerRequestFilter ์ฐธ๊ณ  1
OncePerRequestFilter ์ฐธ๊ณ  2


๐ŸŒˆ ๋Š๋‚€์ 

๊ทธ๋ž˜๋„ Spring Security ๊ธฐ๋ณธ์—์„œ ๋ฐฐ์› ๋˜ ๊ฑฐ์— ๋”ํ•ด์ ธ์„œ ๋ฐฐ์šฐ๋‹ˆ ๊ทธ๋ž˜๋„ ๋‚ซ๋‹ค ..!
ํ•˜์ง€๋งŒ ์—ฌ์ „ํžˆ ์–ด๋ ค์›€ ..

0๊ฐœ์˜ ๋Œ“๊ธ€