๐Ÿƒ Spring Security

 

๐Ÿƒโ€โ™‚๏ธย Quick Start

1. ์˜์กด์„ฑ ์ถ”๊ฐ€

maven

<dependency>
    <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-security</artifactId>
</dependency>

Gradle

implementation "org.springframework.boot:spring-boot-starter-security"

2. Hello Spring Security

classpath์— Spring Security๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ์Šคํ”„๋ง ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
์‹คํ–‰ ํ›„ ์ฝ˜์†”์„ ๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ถœ๋ ฅ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์•„๋ž˜์˜ ์ถœ๋ ฅ์„ ํ†ตํ•ด์„œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ๊ฐ€ ์ ์šฉ๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

2023-10-11T16:15:34.331+09:00  WARN 1644 --- [  restartedMain] .s.s.UserDetailsServiceAutoConfiguration :

Using generated security password: 5451a8c2-a100-43ef-843c-7fb621b5c73b

ํ„ฐ๋ฏธ๋„์„ ์‹คํ–‰ํ•œ ๋’ค ์—”๋“œํฌ์ธํŠธ URL์— ๋Œ€ํ•œ curl ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ถœ๋ ฅ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

curl -i http://localhost:8080/hello
HTTP/1.1 401
Set-Cookie: JSESSIONID=AC7913E4BD60253DAC7D19E775107B7B; Path=/; HttpOnly
WWW-Authenticate: Basic realm="Realm"
...

์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ๋Š” 401 ์‘๋‹ต๊ณผ ํ•จ๊ป˜ ์ ‘๊ทผ์„ ๊ฑฐ๋ถ€ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
์›น ๋ธŒ๋ผ์šฐ์ €๋ฅผ ํ†ตํ•ด์„œ ์ ‘์†์„ ์‹œ๋„ํ•˜๊ฒŒ ๋˜๋ฉด ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€๊ฐ€ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.
์„ค์ • ์ •๋ณด๋ฅผ ์ž‘์„ฑํ•˜๊ธฐ ์ „์ด๋ผ Default ์„ค์ •์ด ์ ์šฉ๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
๋ชจ๋“  ์—”๋“œํฌ์ธํŠธ URL์— ์š”์ฒญํ•  ๊ฒฝ์šฐ ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธํ•ฉ๋‹ˆ๋‹ค.
Username์— โ€˜userโ€™๋ฅผ ์ž…๋ ฅํ•˜๊ณ  Password์—๋Š” Console์—์„œ Log๋กœ ํ™•์ธํ•œ password๋ฅผ ์ž…๋ ฅํ•˜์—ฌ ์ ‘์†ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Spring Security Studyโ€‹

Spring Security Guide

๋“ค์–ด๊ฐ€๊ธฐ ์ „ ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ์˜ ์ปจ์…‰์„ ๊นŠ์ด ์žˆ๊ฒŒ ์ดํ•ดํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ๊ณต์‹ ์‚ฌ์ดํŠธ์˜ ๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”.
๋ณธ ๊ธ€์€ ๊ธฐ๋ณธ์ ์ธ API ์„œ๋น„์Šค์— ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ ๋ฐ JWT ์ ์šฉ์„ ๋ชฉ์ ์œผ๋กœ ํ•ฉ๋‹ˆ๋‹ค.

Spring Security :: Spring Security

1. Architecture

์ „์ฒด ์‹œ๋‚˜๋ฆฌ์˜ค

  1. ์‚ฌ์šฉ์ž๋Š” ํšŒ์›๊ฐ€์ž…(/api/v1/auth/signup)์„ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค.
  2. ์‚ฌ์šฉ์ž๋Š” ๊ฐ€์ž…ํ•œ ๊ณ„์ •์„ ์ด์šฉํ•˜์—ฌ ๋กœ๊ทธ์ธ(/api/v1/signin)ํ•ฉ๋‹ˆ๋‹ค.
  3. ๊ณ„์ • ์ธ์ฆ์— ์„ฑ๊ณตํ•œ ์‚ฌ์šฉ์ž๋Š” ์ž์›(/api/v1/resource)์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•œ ์š”์ฒญ(Request)์„ ์„œ๋ฒ„์— ๋ณด๋ƒ…๋‹ˆ๋‹ค.

ํšŒ์›๊ฐ€์ž…

  1. ์‚ฌ์šฉ์ž๋Š” ์„œ๋น„์Šค์— ํšŒ์›๊ฐ€์ž…์„ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž์˜ ์š”์ฒญ ์ •๋ณด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ User ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž์˜ ์•”ํ˜ธ๋Š” PasswordEncoder์— ์˜ํ•ด์„œ ์•”ํ˜ธํ™”๋ฉ๋‹ˆ๋‹ค.
  2. User ๊ฐ์ฒด๋Š” UserRepository๋ฅผ ํ†ตํ•˜์—ฌ Database์— ์ €์žฅ๋ฉ๋‹ˆ๋‹ค.

๋กœ๊ทธ์ธ

Spring Security Studyโ€‹

  1. ์‚ฌ์šฉ์ž์˜ ๋กœ๊ทธ์ธ ์š”์ฒญ์ด ์˜ค๋ฉด UsernamePasswordAuthenticationFilter๊ฐ€ Authentication ํƒ€์ž…์ธ UsernamePasswordAuthenticationToken์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  2. AuthenticationManager๋Š” ์‚ฌ์šฉ์ž ์ธ์ฆ๊ณผ ๊ด€๋ จํ•œ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž ์ธ์ฆ์„ ์œ„ํ•ด UsernamePasswordAuthenticationToken์€ AuthenticationManager๋กœ ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค.
  3. username ๋˜๋Š” password๊ฐ€ ๊ฒ€์ฆ์— ์‹คํŒจํ•œ๋‹ค๋ฉด RememberMeService.loginFail๊ณผ AuthenticationFailureHandler๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๋Š” 403 ์‘๋‹ต์„ ๋ฐ›๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
  4. ์‚ฌ์šฉ์ž ๊ฒ€์ฆ์— ์„ฑ๊ณตํ•œ๋‹ค๋ฉด Database์—์„œ ์‚ฌ์šฉ์ž๋ฅผ ๊ฒ€์ƒ‰ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์ผ์น˜ํ•˜๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์—†๋‹ค๋ฉด ์š”์ฒญ์ž์—๊ฒŒ 403 ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. 2๋ฒˆ ๊ณผ์ •์—์„œ ์‚ฌ์šฉ์ž ์ธ์ฆ์„ ์‹œ๋„ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด ๊ณผ์ •์„ ๊ทธ๋ ‡๊ฒŒ ์ค‘์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ดํ›„ ๊ฒ€์ƒ‰๋œ ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ JwtTokenProvider์— ์ „๋‹ฌํ•˜์—ฌ JWT ์ƒ์„ฑ์„ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  JWT๊ฐ€ JSON ์‘๋‹ต์— ์บก์Šํ™”๋˜์–ด ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค.

์ž์› ์š”์ฒญ

  1. ์‚ฌ์šฉ์ž๊ฐ€ ์ž์›์— ๋Œ€ํ•œ ์š”์ฒญ์„ ์‹œ๋„ํ•˜๊ฒŒ ๋˜๋ฉด, ํ•ด๋‹น ์š”์ฒญ์€ JwtAuthenticationFilter๋กœ ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค. SecurityFilterChain์— ๋“ฑ๋ก๋œ JwtAuthenticationFilter์€ ์ปค์Šคํ…€๋œ ํ•„ํ„ฐ์ž…๋‹ˆ๋‹ค.
  2. ๋ณดํ˜ธ๋ฐ›๊ณ  ์žˆ๋Š” ์ž์›์— ๋Œ€ํ•œ ์š”์ฒญ์— JWT๊ฐ€ ์—†์„ ๊ฒฝ์šฐ ์š”์ฒญ์ž์—๊ฒŒ 403 ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
  3. JWT๊ฐ€ ์กด์žฌํ•  ๊ฒฝ์šฐ Jwt๋กœ๋ถ€ํ„ฐ ์‚ฌ์šฉ์ž ID(Subject)๋ฅผ ์ถ”์ถœํ•˜๊ธฐ ์œ„ํ•ด JwtTokenProvider๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž ID๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ์ถ”์ถœ๋˜์ง€ ์•Š์„ ๊ฒฝ์šฐ 403 ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
  4. ๋งŒ์•ฝ ์‚ฌ์šฉ์ž ID๊ฐ€ ์ถ”์ถœ๋˜์—ˆ๋‹ค๋ฉด, ID๋ฅผ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ํ•˜์—ฌ UserDetailService๋ฅผ ๊ตฌํ˜„ํ•œ CustomUserDetailsService์˜ loadByUserId()๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.
  5. Database์— ์‚ฌ์šฉ์ž ์ •๋ณด๊ฐ€ ์—†๋‹ค๋ฉด, ์š”์ฒญ์ž์—๊ฒŒ 403 ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
  6. ์ธ์ฆ ์„ฑ๊ณต ์‹œ ์‚ฌ์šฉ์ž ์ •๋ณด๋Š” UsernamaPasswordAuthenticationToken์— ์บก์Šํ™”๋˜์–ด SecurityContextHolder์— ์ €์žฅ๋ฉ๋‹ˆ๋‹ค.
  7. ์ดํ›„ ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ์˜ ์ธ๊ฐ€ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค. ์ธ๊ฐ€ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์„ฑ๊ณตํ•  ๊ฒฝ์šฐ ์‚ฌ์šฉ์ž์˜ ์š”์ฒญ์€ ์ปจํŠธ๋กค๋Ÿฌ๋กœ ๋ณด๋‚ด์ง€๋ฉฐ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์ด ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค.

SecurityContextHolder: ์ธ๊ฐ€๋œ ์‚ฌ์šฉ์ž์˜ ์ •๋ณด๊ฐ€ ์ €์žฅ๋œ ์ €์žฅ์†Œ์ž…๋‹ˆ๋‹ค. ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ๋Š” ์ธ์ฆ ์ž‘์—…์— ํ•ด๋‹น ์ •๋ณด๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

2. Demonstration

Github



References
https://spring.io/projects/spring-security
https://medium.com