๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
[Spring]/Spring Security

๋‹น์‹ ์˜ ์ฒซ ํ”„๋กœ์ ํŠธ๋ฅผ ์œ„ํ•œ ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ(2) - ์ธ์ฆ ๋ฐฉ์‹ ๊ฐœ๋…๊ณผ AuthenticationFilter

by ํŒกํŽ‘ํ 2024. 7. 20.
728x90
๐Ÿ“Œ ์ด๋ฒˆ ๊ธ€์—์„œ๋Š” ์ธ์ฆ ๋ฐฉ์‹ ๊ฐœ๋…๊ณผ AuthenticationFilter ๊ตฌํ˜„์— ๋Œ€ํ•ด ๋‹ค๋ฃน๋‹ˆ๋‹ค.

๐Ÿค— ์ €์˜ ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ ๊ตฌํ˜„์€ ์•„๋ž˜์™€ ๊ฐ™์€ ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ๊ธฐ์ค€์œผ๋กœ ํ•ฉ๋‹ˆ๋‹ค.
- ํ”„๋ก ํŠธ ์—”๋“œ์™€ ๋ฐฑ์—”๋“œ๊ฐ€ ๋‚˜๋‰˜์–ด ์ง„ํ–‰๋˜๋Š” ํ”„๋กœ์ ํŠธ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜์—ฌ ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ ์„ค์ •์—์„œ ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€์— ๋Œ€ํ•œ ์„ค์ •์„ ๋”ฐ๋กœ ํ•˜์ง€ ์•Š์Œ
- JWT ํ† ํฐ ์ธ์ฆ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•จ
- ํ† ํฐ ๊ด€๋ฆฌ์— redis๋ฅผ ์ด์šฉํ•จ

 

๐Ÿ™‰ ์ด์ „ ๊ธ€ ๋ณด๊ธฐ

์ฒซ ๋ฒˆ์งธ ๊ธ€๋ถ€ํ„ฐ ์ •๋…ํ•˜์‹œ๋ฉด ๋ณด๋‹ค ์‰ฝ๊ฒŒ ์ดํ•ดํ•˜์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค!

https://suzuworld.tistory.com/438 - ๋‹น์‹ ์˜ ์ฒซ ํ”„๋กœ์ ํŠธ๋ฅผ ์œ„ํ•œ ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ ํ†บ์•„๋ณด๊ธฐ

์ด์ „ ๊ธ€

https://suzuworld.tistory.com/439 - SecurityConfig ๊ตฌ์„ฑํ•˜๊ธฐ

 

๐Ÿ“– ๋ชฉ์ฐจ

์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ ํ†บ์•„๋ณด๊ธฐ

SecurityConfig ๊ตฌ์„ฑํ•˜๊ธฐ

์ธ์ฆ ๋ฐฉ์‹ ๊ฐœ๋…๊ณผ AuthenticationFilter (ํ˜„์žฌ ๊ธ€)

 

๐Ÿค” ๋“ค์–ด๊ฐ€๊ธฐ ์ „์—

<๊ตฌ๊ธ€ ์ด๋ฏธ์ง€์—์„œ ๊ฒ€์ƒ‰ํ•˜๋ฉด ํ”ํžˆ ๋‚˜์˜ค๋Š” ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ ์ธ์ฆ ์•„ํ‚คํ…์ฒ˜>

  • ์ง€๋‚œ ๊ธ€์—์„œ๋Š” Spring Security๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์ „์— ์„ค์ •ํ•ด์•ผ ํ•  Configuration์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์•˜์Šต๋‹ˆ๋‹ค.
  • ์ด์ œ ๋ณธ๊ฒฉ์ ์ธ ๊ตฌํ˜„์„ ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.
  • ๋จผ์ € ์šฐ๋ฆฌ๊ฐ€ ์–ด๋–ค ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•ด์•ผ ํ• ์ง€ ์ƒ๊ฐํ•ด ๋ด…์‹œ๋‹ค.
    • ๋กœ๊ทธ์ธ, ๋กœ๊ทธ์•„์›ƒ์ด ๋‹น์—ฐํžˆ ํ•„์š”ํ•˜๊ฒ ์ฃ ?
    • ๊ทธ๋ฆฌ๊ณ  ๋กœ๊ทธ์ธ ์ดํ›„ ๊ฐ ์š”์ฒญ์— ๋งž๋Š” ์ธ์ฆ ๋ฐ ๊ถŒํ•œ์— ๋Œ€ํ•ด ๊ฒ€์‚ฌํ•˜์—ฌ ํ†ต๊ณผ์‹œํ‚ค๊ฑฐ๋‚˜ ์ž…๊ตฌ์ปทํ•˜๋Š” ๊ฒ€์ฆ ๋กœ์ง์ด ํ•„์š”ํ•  ๊ฒ๋‹ˆ๋‹ค.
  • ์ฒซ ๊ธ€๋ถ€ํ„ฐ ์–ธ๊ธ‰ํ–ˆ์ง€๋งŒ ์ €ํฌ๋Š” ์‚ฌ์šฉ์ž์˜ ์ธ์ฆ ์ •๋ณด๋ฅผ ๋‹ค๋ฃฐ ๋ฐฉ๋ฒ• ์ค‘ ํ† ํฐ ๊ด€๋ฆฌ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•  ๊ฒ๋‹ˆ๋‹ค.
  • ๋”ฐ๋ผ์„œ ์ด๋ฒˆ ๊ธ€์—๋Š” ์‚ฌ์šฉ์ž์˜ ์ธ์ฆ ์ •๋ณด๋ฅผ ๋‹ค๋ฃจ๋Š” ๊ฐœ๋…๊ณผ ์œ„ ๊ทธ๋ฆผ์˜ 1 ~3๋ฒˆ์— ํ•ด๋‹นํ•˜๋Š” ๋ถ€๋ถ„์„ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

๐Ÿ‘ฎ๐Ÿป‍โ™€๏ธ ์‚ฌ์šฉ์ž ์ธ์ฆ ์ •๋ณด ๊ด€๋ฆฌ ๋ฐฉ์‹

  • ์•„๋งˆ ๋Œ€๋ถ€๋ถ„ ์ดํ•ดํ•˜๊ณ  ๊ณ„์‹œ๊ฒ ์ง€๋งŒ ํ˜น์‹œ๋‚˜ ์ดํ•ด๋ณด๋‹ค๋Š” ๊ตฌํ˜„์— ์•ž์„  ๋ถ„๋“ค์„ ์œ„ํ•ด ์•„์ฃผ ๊ฐ„๋‹จํžˆ ์„ค๋ช…ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.
  • ๋กœ๊ทธ์ธ์„ ํ•˜๋ฉด ์‚ฌ์šฉ์ž๊ฐ€ ์„œ๋ฒ„์— ์ž์‹ ์˜ ์•„์ด๋””์™€ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ „๋‹ฌํ•˜์—ฌ ํ•ด๋‹น ์ •๋ณด๊ฐ€ ์„œ๋ฒ„์— ์ €์žฅ๋œ ์‚ฌ์šฉ์ž ์ •๋ณด์™€ ์ผ์น˜ํ•จ์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
  • ๊ทธ๋Ÿฐ๋ฐ, HTTP ํ†ต์‹ ์˜ ๋Œ€ํ‘œ์ ์ธ ํŠน์ง•์ด ์žˆ์ฃ ? ๋ฐ”๋กœ ๋ฌด์ƒํƒœ์„ฑ(Stateless)์ž…๋‹ˆ๋‹ค. 
    • ์ฆ‰, HTTP๋Š” ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„ ๊ฐ„์˜ ํ†ต์‹ ์ด ๋…๋ฆฝ์ ์ด๋ฉฐ ๊ฐ ์š”์ฒญ์€ ์ด์ „ ์š”์ฒญ๊ณผ ๊ด€๋ จ์ด ์—†์Šต๋‹ˆ๋‹ค.
  • ์šฐ๋ฆฌ๊ฐ€ ๋กœ๊ทธ์ธ์„ ํ•˜๊ณ  ๋‚˜์„œ ๊ฐœ์ธ์ •๋ณด๊ฐ€ ๋“ค์–ด์žˆ๋Š” ๋‚ด ํ”„๋กœํ•„ ๋ณด๊ธฐ ์กฐํšŒ๋ฅผ ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ด…์‹œ๋‹ค.
  • ์šฐ๋ฆฌ๋Š” ๋กœ๊ทธ์ธ๋งŒ ํ–ˆ์„ ๋ฟ์ž…๋‹ˆ๋‹ค. ์ž์‹ ์˜ ํ”„๋กœํ•„ ์กฐํšŒ๋ฅผ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด [๋‚ด ํ”„๋กœํ•„ ๋ณด๊ธฐ] ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅธ๋‹ค๋ฉด ํ•ด๋‹น ์š”์ฒญ์€ ์ด์ „ ๋กœ๊ทธ์ธ๊ณผ๋Š” ์ „ํ˜€ ๋ฌด๊ด€ํ•œ ์š”์ฒญ์ด ๋ฉ๋‹ˆ๋‹ค.
  • ํ•ด๋‹น ์š”์ฒญ์— ๋‹ค์‹œ ๋˜ ๋กœ๊ทธ์ธ ์ •๋ณด๋ฅผ ์‹ฃ๊ฑฐ๋‚˜ ํ•˜์ง€ ์•Š์œผ๋ฉด ์„œ๋ฒ„ ์ž…์žฅ์—์„œ๋Š” ์ด ์š”์ฒญ์ด ์ธ๊ฐ€๋œ ์š”์ฒญ์ธ์ง€๋ฅผ ํ™•์ธํ•  ๋ฐฉ๋ฒ•์ด ์—†๋Š” ๊ฒƒ์ด์ฃ .
  • ๊ทธ๋ ‡๋‹ค๊ณ  ๋ชจ๋“  ์š”์ฒญ์— ๋งค๋ฒˆ ๋กœ๊ทธ์ธ ์•„์ด๋””์™€ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•œ๋‹ค๋ฉด ๋ง๋„ ์•ˆ ๋˜๊ฒ ์ฃ ..
  • ๊ทธ๋ž˜์„œ ๋กœ๊ทธ์ธ์„ ์„ฑ๊ณตํ•˜๋ฉด ์‚ฌ์šฉ์ž ์ธ์ฆ์„ ํ–ˆ๋‹ค๋Š” ์ผ์ข…์˜ ์ถœ์ž…์ฆ(?)์„ ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๋ฐœ๊ธ‰๋ฐ›์•„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๊ฐ€ ๋‹ค์Œ ์š”์ฒญ์ด ์žˆ์„ ๋•Œ๋งˆ๋‹ค ์„œ๋ฒ„์—๊ฒŒ ์š”์ฒญ ์ •๋ณด์— ๋„ฃ์–ด ๋ณด๋‚ด๋ฉด์„œ ์ถ”๊ฐ€ ์ธ์ฆ ์—†์ด ์›ํ•˜๋Š” ์š”์ฒญ์„ ์ง„ํ–‰ํ•˜๋Š” ๋ฐฉ์‹์ด ์‚ฌ์šฉ๋˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

๐Ÿคฏ ์ด ๋ฐฉ์‹์—๋Š” ๋Œ€ํ‘œ์ ์œผ๋กœ ์„ธ์…˜,  ์ฟ ํ‚ค,  ํ† ํฐ ๊ด€๋ฆฌ ๋ฐฉ์‹์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์„ธ์…˜(Session)

  • ์„œ๋ฒ„ ์ธก์—์„œ ์‚ฌ์šฉ์ž ์ธ์ฆ ์ •๋ณด๋ฅผ ์ €์žฅํ•˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค.
  • ๋ฌด์ƒํƒœ HTTP ํ†ต์‹ ์—์„œ ์‚ฌ์šฉ์ž ์ธ์ฆ ์ •๋ณด๋ฅผ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ์„œ๋ฒ„ ์ธก์— ์„ธ์…˜์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • ์„œ๋ฒ„์—์„œ ๋กœ๊ทธ์ธ์„ ์„ฑ๊ณตํ•˜๋ฉด ์„ธ์…˜ ID๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ํด๋ผ์ด์–ธํŠธ์— ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.
  • ํด๋ผ์ด์–ธํŠธ๋Š” ์ดํ›„ ์„œ๋ฒ„์™€ ํ†ต์‹ ํ•  ๋•Œ ์ด ์„ธ์…˜ ID๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์ค„ ์ •๋ณด๊ฐ€ ์‚ฌ์šฉ์ž์˜ ์ •๋ณด ๋Œ€์‹  ์„ธ์…˜ ID์ด๋ฏ€๋กœ ์ •๋ณด ๋ณด์•ˆ์— ๊ฐ•ํ•ฉ๋‹ˆ๋‹ค.
  • ์„œ๋ฒ„์— ์‚ฌ์šฉ์ž ์ธ์ฆ ์ •๋ณด๊ฐ€ ์ €์žฅ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์„œ๋ฒ„ ๋ฆฌ์†Œ์Šค๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

 

์ฟ ํ‚ค(Cookie)

ํด๋ผ์ด์–ธํŠธ ์ธก์—์„œ ์‚ฌ์šฉ์ž ์ธ์ฆ ์ •๋ณด๋ฅผ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.

์„œ๋ฒ„์—์„œ ๋ณ„๋„๋กœ ์‚ฌ์šฉ์ž ์ธ์ฆ ์ •๋ณด๋ฅผ ์ €์žฅํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ์„œ๋ฒ„ ๋ฆฌ์†Œ์Šค ์‚ฌ์šฉ์ด ์ƒ๋Œ€์ ์œผ๋กœ ์ ๋‹ค๋Š” ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

ํด๋ผ์ด์–ธํŠธ์— ์‚ฌ์šฉ์ž ์ธ์ฆ ์ •๋ณด๊ฐ€ ์ €์žฅ๋˜์–ด ์žˆ์–ด ์ •๋ณด ๋ณด์•ˆ์ด ์ƒ๋Œ€์ ์œผ๋กœ ์•ฝํ•˜๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

 

JWT(JSON Web Token)

์„œ๋ฒ„๊ฐ€ ์‚ฌ์šฉ์ž ์ธ์ฆ ์ •๋ณด๋ฅผ ํ† ํฐ์— ์•”ํ˜ธํ™”ํ•˜๊ณ  ๋ณด๋‚ด๋ฉด ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ด๋ฅผ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.

์ดํ›„ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ํ† ํฐ์„ ๊ฐ€์ง€๊ณ  ์„œ๋ฒ„์™€ ํ†ต์‹ ํ•ฉ๋‹ˆ๋‹ค.

ํด๋ผ์ด์–ธํŠธ๊ฐ€ ํ† ํฐ์„ ์‚ฌ์šฉํ•˜์—ฌ ์„œ๋ฒ„์™€ ํ†ต์‹ ํ•˜๋ฏ€๋กœ ์„œ๋ฒ„ ๋ฆฌ์†Œ์Šค ์‚ฌ์šฉ์ด ์ ๊ณ , ํ™•์žฅ์„ฑ์ด ๋†’์Šต๋‹ˆ๋‹ค.

 

๐Ÿƒ๐Ÿป๐Ÿƒ๐Ÿป๐Ÿƒ๐Ÿป๐Ÿƒ๐Ÿป๐Ÿƒ๐Ÿป๐Ÿƒ๐Ÿป๐Ÿƒ๐Ÿป๐Ÿƒ๐Ÿป๐Ÿƒ๐Ÿป

๋ณด๋‹ค ์ž์„ธํ•œ ์ฐจ์ด๋Š” ๊ฒ€์ƒ‰์„ ํ†ตํ•ด ์•Œ์•„๋ด…์‹œ๋‹ค!

 

โš™๏ธ Member ๊ด€๋ จ ์„ธํŒ…

  • ๋ณธ๊ฒฉ์ ์ธ ๊ตฌํ˜„์— ์•ž์„œ Member ๊ด€๋ จ ๊ธฐ๋ณธ ์„ธํŒ…์„ ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.
  • ์—ฌ๋Ÿฌ๋ถ„์ด ๋ฌด์—‡์„ ๊ตฌํ˜„ํ•˜๋“  ๋ถ„๋ช… ํšŒ์›๊ฐ€์ž…๊ณผ ๋กœ๊ทธ์ธ, ๋กœ๊ทธ์•„์›ƒ ๊ตฌํ˜„์ด ๋“ค์–ด๊ฐˆ ํ…๋ฐ์š”.
  • ์ œ๊ฐ๊ฐ ๋‹ค๋ฅธ ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ํ•  ํ…Œ๋‹ˆ ์—ฌ๊ธฐ์„œ๋Š” ๊ด€๋ จ๋œ ๋‚ด์šฉ์„ ๋งค์šฐ ๊ฐ„๋žตํ•˜๊ฒŒ๋งŒ ๋ณด์—ฌ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค. ์„ค๋ช…๋„ ์ƒ๋žตํ•ฉ๋‹ˆ๋‹ค.

 

bulid.gradle

// JPA
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
// H2
runtimeOnly 'com.h2database:h2'
  • ๊ฐ„ํŽธํ•œ ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•ด JPA๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • ์ง€๋‚œ ๊ธ€์—์„œ ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ ์‹œ h2๋Š” ๋”ฐ๋กœ ์˜์กด์„ฑ์„ ์ถ”๊ฐ€ํ•ด ์คฌ์Šต๋‹ˆ๋‹ค.

 

MemberRepository

public interface MemberRepository extends JpaRepository<Member, Long> {
}
  • JPA์˜ ๊ธฐ๋ณธ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

 

MemberDto 

public class MemberDto {

    @Getter
    public static class Enroll {
        private String memberId;
        private String password;
        private String username;
    }

    @Getter
    public static class Login {
        private String memberId;
        private String password;
    }
}
  • ํšŒ์› ์ •๋ณด๋กœ ๊ฐ€์งˆ ํ•„๋“œ๋Š” ์•„์ด๋””, ๋น„๋ฐ€๋ฒˆํ˜ธ, ํšŒ์› ์ด๋ฆ„(๋‹‰๋„ค์ž„) ์„ธ ๊ฐœ์ž…๋‹ˆ๋‹ค.
  • ํšŒ์› ๊ฐ€์ž…์€ ํšŒ์› ์ •๋ณด๋ฅผ ๋ชจ๋‘ ์ž…๋ ฅ๋ฐ›์•„์•ผ ํ•˜๋‹ˆ ํ•„๋“œ ์„ธ ๊ฐœ๋ฅผ ๋ชจ๋‘ ๊ฐ€์ง‘๋‹ˆ๋‹ค.
  • ๋กœ๊ทธ์ธ์€ ํšŒ์› ์•„์ด๋””์™€ ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ํ•„์š”ํ•˜๋‹ˆ ๋‘ ๊ฐœ์˜ ํ•„๋“œ๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค.

 

Member

@Entity
@Getter
@Setter
@NoArgsConstructor
public class Member {

    @Id
    private String memberId;
    private String password;
    private String username;
}
  • ์—”ํ‹ฐํ‹ฐ ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค.
  • ๊ฐ„๋‹จํ•œ ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•ด @Setter๋ฅผ ์‚ฌ์šฉํ•˜์˜€์ง€๋งŒ, ํ”„๋กœ์ ํŠธ์—์„œ๋Š” ์—”ํ‹ฐํ‹ฐ์—์„œ์˜ ์‚ฌ์šฉ์„ ์ง€์–‘ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 

MemberController

@RestController
@RequiredArgsConstructor
public class MemberController {

    private final MemberRepository memberRepository;

    @PostMapping("/members")
    public ResponseEntity<?> addMember(@RequestBody MemberDto.Enroll enroll) {

        Member member = new Member();
        member.setMemberId(enroll.getMemberId());
        member.setPassword(enroll.getPassword());
        member.setUsername(enroll.getUsername());

        memberRepository.save(member);

        return new ResponseEntity<>(member, HttpStatus.CREATED);
    }
}
  • ๊ฐ„๋‹จํ•œ ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•ด ์ปจํŠธ๋กค๋Ÿฌ์— ์ „๋ถ€ ๋ชฐ์•„๋„ฃ์—ˆ์Šต๋‹ˆ๋‹ค.
  • DTO๋กœ ๋ฐ›์€ ํ•„๋“œ๋ฅผ ์—”ํ‹ฐํ‹ฐ๋กœ ์˜ฎ๊ธฐ๊ณ  ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅํ•˜๋Š” ๊ฐ„๋‹จํ•œ ํšŒ์›๊ฐ€์ž… ๋กœ์ง์ž…๋‹ˆ๋‹ค.

 

h2-conole & application.yml

spring:
  h2:
    console:
      enabled: true # H2 Console์„ ์‚ฌ์šฉ ์—ฌ๋ถ€ (H2 Console์€ H2 Database๋ฅผ UI)
      path: /h2-console # H2 Console์˜ ๊ฒฝ๋กœ
  datasource:
    # H2 ์ ‘์† ์ •๋ณด
    url: jdbc:h2:mem:security # In-Memory Mode๋กœ ์‚ฌ์šฉํ•จ
    username: sa  # H2 ์ ‘์† ์‹œ username ์ •๋ณด (์ž์œ  ์ž…๋ ฅ)
    password:     # H2 ์ ‘์† ์‹œ password ์ •๋ณด (์ž์œ  ์ž…๋ ฅ)
    driver-class-name: org.h2.Driver # Database๋ฅผ H2๋กœ ์‚ฌ์šฉํ•จ์„ ๋ช…์‹œ
  • h2 ์„ค์ • ์ •๋ณด์ž…๋‹ˆ๋‹ค. ์ฐธ๊ณ ํ•˜์‹œ๋ฉด ๋  ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 

SecurityConfig

  • Spring security Config์— ์•ฝ๊ฐ„ ๋ณ€๊ฒฝ์‚ฌํ•ญ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

 

// h2 ์‚ฌ์šฉ์‹œ ๋ถ™์—ฌ์•ผํ•จ
.headers(headers -> headers.frameOptions(HeadersConfigurer.FrameOptionsConfig::sameOrigin))

 

  • ํ˜„์žฌ ํ…Œ์ŠคํŠธ๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋กœ h2๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
  • h2์˜ ์›น ์ฝ˜์†”์€ iframe์„ ํ†ตํ•ด ํ™”๋ฉด์„ ๊ตฌ์„ฑํ•œ๋‹ค๊ณ  ํ•˜๋Š”๋ฐ์š”. ๋งŒ์•ฝ iframe์— ๋Œ€ํ•œ ๋ชจ๋“  ์š”์ฒญ์„ ํ—ˆ์šฉํ•˜๋ฉด ๋””๋„์Šค ๊ณต๊ฒฉ, ํด๋ฆญ์žฌํ‚น ๊ณต๊ฒฉ์— ์ทจ์•ฝํ•ด์งˆ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๊ธฐ๋ณธ ์„ค์ •์€ iframe์„ ์‚ฌ์šฉํ•˜์ง€ ๋ชปํ•˜๋„๋ก DENY๋กœ ์„ค์ •ํ•˜๊ณ  ์žˆ๋‹ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ—ˆ์šฉํ•˜๋Š” ์„ค์ •์ž…๋‹ˆ๋‹ค.
    • ์ด ์„ค์ •์„ ํ•˜์ง€ ์•Š์œผ๋ฉด h2 ์›น ์ฝ˜์†” ์‚ฌ์šฉ์ด ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. 
    • ์ด ์„ค์ •์€ ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•œ ์„ค์ •์ด๋ฏ€๋กœ h2๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ๋ถˆํ•„์š”ํ•œ ์„ค์ •์ž…๋‹ˆ๋‹ค.
  • ์•„๋ž˜๋Š” ๊ด€๋ จ ์„ค๋ช… ๋งํฌ์ž…๋‹ˆ๋‹ค.

https://dukcode.github.io/spring/h2-console-with-spring-security/

 

Spring Security์—์„œ H2 Console ์‚ฌ์šฉํ•˜๊ธฐ

Spring Security์—์„œ H2 Console ์‚ฌ์šฉํ•˜๊ธฐ

dukcode.github.io

 

 

// ์‹œํ๋ฆฌํ‹ฐ ์ธ์ฆ์„ ํ•˜์ง€ ์•Š๋Š” ์š”์ฒญ์— ์—”๋“œํฌ์ธํŠธ ์ถ”๊ฐ€
.requestMatchers("/login", "/enroll", "/h2-console/**").permitAll()
  • ๋˜ํ•œ, ๊ธฐ์กด ๋กœ๊ทธ์ธ api ์—”๋“œํฌ์ธํŠธ ์™ธ์— ์ถ”๊ฐ€๋กœ ํšŒ์›๊ฐ€์ž…๊ณผ h2-console๊ณผ ๊ด€๋ จ๋œ ์š”์ฒญ๋„ ์ „๋ถ€ ์ธ์ฆํ•˜์ง€ ์•Š๊ฒŒ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค.
    • ํšŒ์›๊ฐ€์ž…๊ณผ ๋กœ๊ทธ์ธ, h2-console ๋ชจ๋‘ ์ธ์ฆ ํ›„ ์ ‘๊ทผ ๋ฐฉ์‹์ด ๋ถˆํ•„์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์„ค์ •ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

ํšŒ์› ๊ฐ€์ž… ํ…Œ์ŠคํŠธ

  • PostMan์œผ๋กœ ํ…Œ์ŠคํŠธํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ํšŒ์›๊ฐ€์ž…์„ ํ•˜๋Š” ๊ณผ์ •์ž…๋‹ˆ๋‹ค.
  • h2์— ์ ‘์†ํ•˜๋ฉด ์„ฑ๊ณต์ ์œผ๋กœ ์ €์žฅ๋จ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๐ŸŽ‰ ๋ณธ๊ฒฉ์ ์ธ ๊ตฌํ˜„ ์‹œ์ž‘

  • ์•„ํ‚คํ…์ฒ˜์—์„œ ์ด๋ฒˆ ๊ธ€์—์„œ ๊ตฌํ˜„ํ•  ๋ถ€๋ถ„๋งŒ ๊ฐ€์ ธ์™”์Šต๋‹ˆ๋‹ค.
  • ์œ„์˜ ์„ค๋ช…์ด ๊ธธ์—ˆ์œผ๋‹ˆ ์กฐ๊ธˆ ์ •๋ฆฌํ•ด ๋ด…์‹œ๋‹ค.
  • ์šฐ๋ฆฌ๋Š” ์œ„์—์„œ ํšŒ์›๊ฐ€์ž…์„ ์„ฑ๊ณตํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ํšŒ์› ์•„์ด๋””๋Š” "aaa", ๋น„๋ฐ€๋ฒˆํ˜ธ๋Š” "bbb", ์‚ฌ์šฉ์ž ์ด๋ฆ„์€ "๊น€๊ฐœ๋˜ฅ"์ž…๋‹ˆ๋‹ค.
  • ์ด์ œ ์šฐ๋ฆฌ๋Š” ๋กœ๊ทธ์ธ์„ ๊ตฌํ˜„ํ•ด ๋ณผ ๊ฒ๋‹ˆ๋‹ค.
  • ์ดํ•˜๋Š” ์ด ๊ธ€์—์„œ ๋‹ค๋ฃฐ ๊ตฌํ˜„ ๋ถ€๋ถ„์ž…๋‹ˆ๋‹ค.
    • Http Request๋กœ ์‚ฌ์šฉ์ž์˜ ์•„์ด๋””์™€ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅ๋ฐ›์Šต๋‹ˆ๋‹ค. (1)
    • ์ธ์ฆ ํ•„ํ„ฐ๊ฐ€ ํ•ด๋‹น ๊ฐ’์„ UsernamePasswordAuthenticationToken ๊ฐ์ฒด์— ์‹ฃ์Šต๋‹ˆ๋‹ค. (2)
    • ์ดํ›„ AuthenticationManager์—๊ฒŒ ์ธ์ฆ ์ฒ˜๋ฆฌ ๊ถŒํ•œ์„ ์œ„์ž„ํ•˜์—ฌ ์ดํ›„ ์ฒ˜๋ฆฌ๋ฅผ ์ง„ํ–‰ํ•˜๋„๋ก ์ง€์‹œํ•ฉ๋‹ˆ๋‹ค. (3)

 

JwtAuthenticationFilter(Http Request -> AuthenticationFilter)

  • 1๋ฒˆ์— ํ•ด๋‹นํ•˜๋Š” ๋ถ€๋ถ„์ž…๋‹ˆ๋‹ค. "/login" ์—”๋“œํฌ์ธํŠธ๋กœ ์š”์ฒญ์ด ๋“ค์–ด์˜ค๋ฉด ์ปจํŠธ๋กค๋Ÿฌ์— ๊ฐ€๊ธฐ ์ „ ํ•ด๋‹น ํ•„ํ„ฐ๋ฅผ ๊ฑฐ์น˜๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.
    • ํ•„ํ„ฐ ์ ์šฉ์€ ๋‹ค์Œ ๊ธ€์—์„œ ๋‹ค๋ฃน๋‹ˆ๋‹ค. 
    • ์ด ํด๋ž˜์Šค๋Š” UsernamePasswordAuthenticationFilter์ด๋ž€ ํ•„ํ„ฐ๋ฅผ ์ƒ์†๋ฐ›๋„๋ก ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ ์ด์œ ๋Š”?
      • ์Šคํ”„๋ง์ด ๋กœ๊ทธ์ธ ์ฒ˜๋ฆฌ์— ๋Œ€ํ•œ ํ•„ํ„ฐ๋ฅผ ์ด๋ฏธ ์ž˜ ๋งŒ๋“ค์–ด๋‘์—ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๊ฐ€ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋งŒ๋“œ๋Š” ๊ฒƒ๋ณด๋‹ค ์ด๋ฏธ ์ž˜ ๋งŒ๋“ค์–ด์ง„ ์ฝ”๋“œ๋ฅผ ์ด์šฉํ•˜๋Š” ๊ฒƒ์ด Spring Security๋ฅผ ์“ฐ๋Š” ์ด์œ ๋‹ˆ๊นŒ์š”!
    • ์ด๋ฆ„์œผ๋กœ ์•Œ ์ˆ˜ ์žˆ๋“ฏ์ด Username(Id)์™€ Password๋กœ ๋กœ๊ทธ์ธ ์ธ์ฆ์„ ํ•˜๋Š” ํ•„ํ„ฐ์ธ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.
    • ์ฐธ๊ณ ๋กœ ์ œ๊ฐ€ ๋งŒ๋“  entity์˜ username๊ณผ ์ด username์€ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ์—”ํ‹ฐํ‹ฐ์˜ username์€ ๋‹จ์ˆœํ•œ ๋‹‰๋„ค์ž„์„ ์˜๋ฏธํ•˜๊ณ , ์—ฌ๊ธฐ์„œ์˜ username์€ ํšŒ์› ์•„์ด๋””๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.
  • attemptAuthentication() ๋ฉ”์„œ๋“œ๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋”ฉํ•ด ์ค๋‹ˆ๋‹ค.

 

๋กœ์ง ๊ตฌํ˜„(AuthenticationFilter -> UsernamePasswordAuthenticationToken)

  • ๊ทธ๋ฆผ์˜ 2, 3๋ฒˆ์— ํ•ด๋‹นํ•˜๋Š” ๋ถ€๋ถ„์ž…๋‹ˆ๋‹ค.

 

private final AuthenticationManager authenticationManager;
  • ๋จผ์ € authenticationManager๋ฅผ ์˜์กด์„ฑ ์ฃผ์ž…๋ฐ›์Šต๋‹ˆ๋‹ค.

 

@SneakyThrows

  • Lombok ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ์ œ๊ณตํ•˜๋Š” ์–ด๋…ธํ…Œ์ด์…˜์ž…๋‹ˆ๋‹ค. ์ด ์–ด๋…ธํ…Œ์ด์…˜์€ ๋ฉ”์„œ๋“œ์— ์‚ฌ์šฉ๋˜๋ฉฐ ๋ฉ”์„œ๋“œ ๋‚ด๋ถ€์—์„œ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์˜ˆ์™ธ๋ฅผ ์ž๋™์œผ๋กœ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

 

ObjectMapper objectMapper = new ObjectMapper();
MemberDto.Login loginDto = objectMapper.readValue(request.getInputStream(), MemberDto.Login.class);
  • ์ด๊ณณ์€ ํ•„ํ„ฐ๋‹จ์ด๋ฏ€๋กœ ์ง€๊ธˆ๊ป ์Šคํ”„๋ง์ด ๋Œ€์‹ ํ•ด์ค€ ์ž‘์—…์„ ์ง์ ‘ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
    • ์š”์ฒญ์œผ๋กœ ๋“ค์–ด์˜จ JSON ๋ฐ์ดํ„ฐ๋ฅผ DTO์— ๋งคํ•‘ํ•˜์—ฌ ๋„ฃ์–ด์ฃผ๋Š” ๋“ฑ์˜ ์—ญํ• ์„ ๋งํ•ฉ๋‹ˆ๋‹ค.
    • objectMapper๋Š” ์ด๋Ÿฌํ•œ ๋งคํ•‘ ์—ญํ• ์„ ํ•ด์ฃผ๋Š” ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค.
  • new ํ‚ค์›Œ๋“œ๋กœ objectMapper ์ธ์Šคํ„ด์Šค๋ฅผ ํ•˜๋‚˜ ์ƒ์„ฑํ•˜๊ณ  request.getInputStream()๋ฅผ ํ†ตํ•ด ์š”์ฒญ ๋ฐ์ดํ„ฐ์— ๋“ค์–ด์žˆ๋Š” json์„ MemberDto์˜ Login์— ๋งž์ถฐ ๋งคํ•‘ํ•˜์—ฌ loginDto๋ฅผ ์™„์„ฑํ•ฉ๋‹ˆ๋‹ค. 
UsernamePasswordAuthenticationToken authenticationToken =
new UsernamePasswordAuthenticationToken(loginDto.getEmail(), loginDto.getPassword());

return authenticationManager.authenticate(authenticationToken);
  • ๊ทธ๋‹ค์Œ loginDto์—์„œ memberId์™€ password๋ฅผ ๊บผ๋‚ด UsernamePasswordAuthenticationToken ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์—ฌ authenticationManager์—๊ฒŒ ์ธ์ฆ ์ฒ˜๋ฆฌ๋ฅผ ๋ถ€ํƒํ•ฉ๋‹ˆ๋‹ค.(authenticationManager.authenticate(authenticationToken);)

 

๐Ÿง‘๐Ÿป‍๐Ÿซ  ์ •๋ฆฌ & ๋‹ค์Œ ๊ธ€์—์„œ ๋‹ค๋ฃฐ ๋‚ด์šฉ

  • ์ฒซ ๋ฒˆ์งธ ๊ธ€์—์„œ AuthenticationManager๊ฐ€ ๋งค๋‹ˆ์ €์˜ ์—ญํ• ์„ ๋ถ€์—ฌ๋ฐ›์•„ ์ผ์„ ์ฒ˜๋ฆฌํ•œ๋‹ค๊ณ  ํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ๊ทธ๋Ÿฌ๋‚˜, AuthenticationManager๋Š” interface์ด๋ฏ€๋กœ ์ด๋ฅผ ๊ตฌํ˜„ํ•  ๊ตฌํ˜„์ฒด๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
    • ํ•ด๋‹น ๊ตฌํ˜„์ฒด๊ฐ€ ๋งค๋‹ˆ์ €์˜ ์—ญํ• ์„ ๋ถ€์—ฌ๋ฐ›์„ ๊ฒ๋‹ˆ๋‹ค.
    • ์‚ฌ์šฉ์ž ์ธ์ฆ ์ •๋ณด(id, password)๋ฅผ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ๊ฐ€์ ธ์˜จ ์ •๋ณด์™€ ๋น„๊ตํ•˜๋„๋ก ๋‹ค๋ฅธ ๊ฐ์ฒด์—๊ฒŒ ์˜ค๋”๋ฅผ ๋‚ด๋ฆด ๊ฒ๋‹ˆ๋‹ค.
    • ์ดํ›„ ๊ฒฐ๊ด๊ฐ’์„ ๋ฆฌํ„ด ๋ฐ›์•„ ์„ฑ๊ณต๊ณผ ์‹คํŒจ ์‹œ ๊ฐ๊ฐ ์‘๋‹ต์— ๋Œ€ํ•œ ๊ฒฐ๊ณผ๋ฅผ ์ฒ˜๋ฆฌํ•  ๊ฒ๋‹ˆ๋‹ค.
    • ์ด ๊ณผ์ •์—์„œ ๋กœ๊ทธ์ธ์— ์„ฑ๊ณตํ•œ๋‹ค๋ฉด JWT ํ† ํฐ์„ ๋ฐœ๊ธ‰ํ•˜๊ณ  ์œ ์ €์—๊ฒŒ ์‘๋‹ต ๋ฉ”์‹œ์ง€์™€ ํ•จ๊ป˜ ๋ณด๋‚ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค.
  • ์ด๋ฅผ ์œ„ํ•ด ์šฐ๋ฆฌ๊ฐ€ ๋งŒ๋“  AuthenticationFilter๋ฅผ Config์— ๋“ฑ๋กํ•˜์—ฌ ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ๊ฐ€ ์ด ํ•„ํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • AuthenticationManager์˜ ๊ตฌํ˜„์ฒด๋ฅผ ๋งŒ๋“ค์–ด Config์— ๋“ฑ๋กํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 

 

 

์ฐธ๊ณ 

๋คผํŠผ

https://dukcode.github.io/spring/h2-console-with-spring-security/

 

 

728x90