2022. 8. 23. 08:08ใBack-End ์์ ์ค/Spring Framework

์คํ๋ง ์ํ๋ฆฌํฐ ์ธ ์ก์ :๋ณด์ ๊ธฐ์ด๋ถํฐ OAuth 2๊น์ง
COUPANG
www.coupang.com
"์ด ํฌ์คํ ์ ์ฟ ํก ํํธ๋์ค ํ๋์ ์ผํ์ผ๋ก, ์ด์ ๋ฐ๋ฅธ ์ผ์ ์ก์ ์์๋ฃ๋ฅผ ์ ๊ณต๋ฐ์ต๋๋ค."
์ด ๊ธ์ ์ธํ๋ฐ - Spring Boot ๊ธฐ๋ฐ์ผ๋ก ๊ฐ๋ฐํ๋ Spring Security๋ฅผ ํ์ตํ๋ฉด์ ์ ๋ฆฌํ ๋ด์ฉ ์ ๋๋ค.
GIT HUB ์ฃผ์ : https://github.com/junyharang-coding-study/spring-security-form-auth
๐ ๋ชฉ์ฐจ
โ [Spring Boot] Spring Security Basic - ๊ธฐ๋ณธ API ๋ฐ Filter ์ดํดํธ
โ [Stpring Boot] Spring Security Basic - Spring Security ์ฃผ์ ์ํคํ
์ฒ ์ดํดํธ
โ [Stpring Boot] Spring Security ์ค์ ํ๋ก์ ํธ - ์ธ์ฆ ํ๋ก์ธ์ค Form ์ธ์ฆ ๊ตฌํ(1)
โ [Stpring Boot] Spring Security ์ค์ ํ๋ก์ ํธ - ์ธ์ฆ ํ๋ก์ธ์ค Form ์ธ์ฆ ๊ตฌํ(2)
โ [Stpring Boot] Spring Security ์ค์ ํ๋ก์ ํธ - ์ธ์ฆ ํ๋ก์ธ์ค Ajax ์ธ์ฆ ๊ตฌํ
๐ Form Authentication
๐ฝ ์ธ์ฆ(Authentication) Process ๊ตฌํ
๐ฆ Project ๊ตฌ์ฑํ๊ธฐ
Project ๊ตฌ์ฑ์ ์๋์ ๊ฐ์ด ์งํ์ ํด๋ณด๋ ค๊ณ ํด์.
1. Project ์ด๋ฆ
โข spring-security-formAuth
2. Project ๊ธฐ๋ณธ ๊ตฌ์ฑ
โข ์์กด์ฑ ์ค์ , ํ๊ฒฝ ์ค์ , UI ํ๋ฉด ๊ตฌ์ฑ, ๊ธฐ๋ณธ CRUD ๊ธฐ๋ฅ ๊ตฌํ
โข Spring Seucrity ๊ธฐ๋ฅ์ ์ ์ง์ ์ผ๋ก ๊ตฌํ ๋ฐ ์์ฑ
3. Data Base Management System
โข H2-DB
โข ๊ฐ์์์๋ Postgresql Server๋ฅผ ์ด์ฉํ๋, ์ฃผ๋ํ๋์ ์์ DB ์ด์ฉ
์ต์ด ๊ฐ๊ฐ์ Controller๋ฅผ ๋ง๋ค์ด ์ค๊ฒ์.
๋จผ์ Package Tree ๊ตฌ์กฐ๋ ์๋์ ๊ฐ์ต๋๋ค.




๊ฐ์์์ ํ์๋ฆฌํ๋ฅผ ํตํ Front End Code๋ฅผ ์ด๋ฏธ ๊ตฌ์ฑํด์ ๊ฐ์๊ฐ ์งํ๋๋๋ฐ์.
์ด Code๋ ์ฃผ๋ํ๋ Git Hub์์ ํ์ธํ์ค ์ ์์ต๋๋ค.
์ด๋ฒ์๋ Spring Security Config ์ฆ, ์ค์ ๊ด๋ จ Code๋ฅผ ์์ฑํด ๋ณผ๊ฒ์.
์ฐธ๊ณ ๋ก Spring Security 5.7 Version ์ด์์์ ๋ ์ด์ WebSecurityConfigurerAdapter ์ฌ์ฉ์ ๊ถ์ฅํ์ง ์๊ณ ์์ด์. ์ด ๋ด์ฉ์ ์ด ๊ณณ ๊ณต์ ํํ์ด์ง๋ฅผ ์ฐธ๊ณ ํด ์ฃผ์ธ์!
์์ ๊ฐ์ ์ด์ ๋ก SecurityFilterChain์ Bean์ผ๋ก ๋ฑ๋กํด์ ๊ฐ์์๋ ๋ค๋ฅด๊ฒ Code๊ฐ ์์ฑ ๋์์ต๋๋ค!
๐ก ์ฐธ๊ณ ์ฌํญ
found websecurityconfigureradapter as well as securityfilterchain. please select just one.
SeucityFilterChain์ @Bean ๊ฐ์ฒด๋ก ๋ฑ๋กํ๋ฉด ์์ ๊ฐ์ Error๊ฐ ๋ฐ์ํ์ ๋ ๋์ฒ๋ฒ.
์ด๋ SpringBoot์์ ์ด๋ฏธ default๋ก SecurityFilterChain์ ๋ฑ๋กํ๋๋ฐ, @Bean์ ํตํด ๋๋ค์ ๊ฐ์ฒด ์ฃผ์ ์ ์๋ํ๊ฒ ๋๋ฉด ๋ ์ค ํ๋๋ง ์ด์ฉํ๋ผ๊ณ ๊ฒฝ๊ณ ๋ฅผ ํ๋ ๊ฒ์ด๋ค.
@ConditionalOnDefaultWebSecurity @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
ํด๊ฒฐ ๋ฐฉ์์ผ๋ก ๋ ๊ฐ Annotation์ Class ์ ์ธ๋ฌธ ์์ ์ถ๊ฐํ๊ณ ,
@Order(SecurityProperties.BASIC_AUTH_ORDER)
์ Annotation์ filter Method ์์ ์ถ๊ฐํ๋ฉด ๋๋ค.

์ฐ๋ฆฌ๋ ์ด๋ฒ ์๊ฐ์ Form ์ธ์ฆ ๋ฐฉ์์ ๊ตฌํํ ๊ฑฐ์์.
๊ทธ๋์ ๋ชจ๋ ์์ฒญ์ ๋ํด ์ธ์ฆ์ ๋ฐ๋๋ก ํ์๊ณ (15 ~ 17๋ฒ์งธ ์ค), formLogin()์ผ๋ก ์ธ์ฆ ์ฒ๋ฆฌํ๊ฒ ๋ค๊ณ ์ ์ธ์ ํด ์ฃผ์์ด์.
๐ก ์ฐธ๊ณ ์ฌํญ
๋ง์ฝ ์์ ๊ฐ์ด Controller์ String์ผ๋ก return์ ์ฃผ์์ ๋, ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค๋ฉด Page์ ์ ์ํ ์๊ฐ ์๋ค.
์ด ๋ฌธ์ ๋ thymleaf ๊ด๋ จ Error์ธ๋ฐ, ํ์ฌ ์ฃผ๋ํ๋์ thymleaf ๊ด๋ จ Dependency๋ฅผ ์ถ๊ฐํ์ง ์์๋ค.
Maven Builder๋ฅผ ์ฌ์ฉํ ๊ฒฝ์ฐ pom.xml์ ์๋์ ๊ฐ์ด Dependency๋ฅผ ์ถ๊ฐํด์ค๋ค.
Gradle Builder๋ฅผ ์ฌ์ฉํ ๊ฒฝ์ฐ build.gradle์ ์๋์ ๊ฐ์ด Dependency๋ฅผ ์ถ๊ฐํด ์ค๋ค. 728x90


์ด์ ์์ ๊ฐ์ด ์ธ์ฆ์ ์๋ํด ๋ณผ๊ฒ์!

์ ์์ ์ผ๋ก /home์ ์ ์ํ์์ต๋๋ค!
์ด๋ฒ์๋ Momory์ ์์๋ก ์ฌ์ฉ๋ ์ฌ์ฉ์ ๊ณ์ ์ค์ ์ ํด๋ณผ๊ฒ์.

์์ ๊ฐ์ด ์ธ ๋ช
์ ์ด์ฉ์๋ฅผ ์์๋ก ์์ฑํด ์ฃผ์์ด์.
์ญ์ WebSecurityConfigurerAdpter๋ฅผ ์์ํด์ ํ๋ ๋ฐฉ์์ด ์๋๊ธฐ ๋๋ฌธ์ ์์ ๊ฐ์ด ๊ณต์ ๋ฌธ์์ ๋์ ์๋ ๋ฐฉ์๋๋ก ์งํํ์์ต๋๋ค.

์ด์ ๋ ๊ถํ ์ค์ ์ ํด ์ฃผ์์ด์.
๋จผ์ 53๋ฒ์งธ ์ค์ root Page์ ๋ํด์๋ ๋ชจ๋ ์ด์ฉ์๊ฐ ๋ค ์ ๊ทผ(permitAll())ํ ์ ์๊ฒ ์ฒ๋ฆฌ๋ฅผ ํด์ฃผ์๊ณ , /user๋ผ๋ URI ํ์ ์์์ USER ๊ถํ์ด ์ ๊ทผ ๊ฐ๋ฅํ๊ณ , /manager URI ํ์ ์์์ MANAGER ๊ถํ์ด ์ ๊ทผํ๊ณ , ADMIN๋ ๋ง์ฐฌ๊ฐ์ง๋ก ์ฒ๋ฆฌ๋ฅผ ํด ์ฃผ์์ต๋๋ค.

์ด ๋ Server๋ฅผ ๊ธฐ๋ํ๋ฉด ์ ๊ณผ ๊ฐ์ด Spring Security๋ USER๋ผ๋ ๊ถํ์ Password๋ฅผ ๋ฐ๋ก ๋ง๋ค์ด์ฃผ์ง ์์์.
์๋ํ๋ฉด ์ด๋ฏธ In Memory์ ๊ฐ๊ฐ์ ๊ณ์ ์ ์์ฑํด ์ฃผ์๊ธฐ ๋๋ฌธ์ด์์.

์ต์ด root Page ์ฆ, home์ ๋ชจ๋ ์ด์ฉ์๊ฐ ์ ๊ทผ์ด ๊ฐ๋ฅํ๊ฒ ์ฒ๋ฆฌ๋ฅผ ํ๊ธฐ ๋๋ฌธ์ ์ธ์ฆ ์ฌ๋ถ์ ์๊ด์์ด ์ ๊ทผ์ ํ ์ ์์ด์.
์ด๋ฒ์๋ My Page ์ ์์ ์ํด Navigation Bar์ ๋ง์ดํ์ด์ง๋ฅผ ํด๋ฆญํด ๋ณผ๊ฒ์.

๊ทธ๋ผ Login ์ฐฝ์ ๋ง๋ ์ ์๋ ๊ฒ์ ํ์ธํ ์ ์์ด์.
์๋ํ๋ฉด USER๋ผ๋ ๊ถํ์ ํ์ธํด์ผ ํ๊ธฐ ๋๋ฌธ์ด์์.

USER ๊ณ์ ์ผ๋ก ์ ์์ ์๋ํด ๋ณผ๊ฒ์.

์ด๋ ๊ฒ USER ๊ถํ์ ํ์ฉํ๋ My Page์ ์ ์์ด ๋์์ด์.

์ด ๋, ํด๋น ์ด์ฉ์๊ฐ config ์ฆ, ADMIN ๊ถํ์ด ์๋ ์ด์ฉ์๋ง ์ด์ฉ ๊ฐ๋ฅํ Page์ ์ ์ํ ์ 403 Forbidden Error๋ฅผ ๋ง๋ ์ ์๋ ๊ฒ์ ๋ณผ ์ ์์ด์.
๐ฆ WebIgnore ์ค์
1. js / css / image File ๋ฑ Security Filter๋ฅผ ์ ์ฉํ ํ์๊ฐ ์๋ ์์์ ๋ํ ์ค์ .
Spring Security 5.7 ์ดํ Version ์ฌ์ฉ๋ฒ
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.requestMatchers(PathRequest.toStaticResources()
.atCommonLocations());
}
Spring Security 5.7 ์ด์ Version ์ฌ์ฉ๋ฒ
import com.junyharang.springsecurityformauth.constant.ServiceURIManagement;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
@EnableWebSecurity // Spring Security ์ค์ ํ์ฑํ
@Configuration
public class WebSecurityConfigure {
@Bean
public WebSecurityCustomizer websecurityCustomizer() {
return (web) -> web.ignoring().antMatchers("/css/**", "/js/**", "/img/**", "/lib/**", "/favicon.ico");
}
}
Spring Security๋ Project ๋ด์ ๋ชจ๋ Code์ ๋ํด ๋ณด์ Filter๋ฅผ ํ๋๋ก ๊ธฐ๋ณธ์ ์ผ๋ก ์ค์ ์ด ๋์ด ์์ด์.
๊ทธ๋์ js / css / image ๋ฑ๊ณผ ๊ฐ์ File๋ ๋ฐ๋ก ์ค์ ์ ํด ์ฃผ์ง ์์ผ๋ฉด Spring Security Filter์์ ํด๋น ์ด์ฉ์๊ฐ ์ ๊ทผ ์ฌ๋ถ๋ฅผ ๊ฒ์ฌํ๊ฒ ๋์ด ์์ต๋๋ค.
ํ์ง๋ง, ์ ์์๋ค์ ๋ณด์ ์ค์ ์ด ํ์๊ฐ ์๋ ์น๊ตฌ๋ค์ด์์.
๊ทธ๋์ ์์ ๊ฐ์ด ๋ณด์ ์ค์ ์ด ํ์ ์๋ ์ค์ ์ ์ถ๊ฐํด์ฃผ์ด์ผ ํฉ๋๋ค.

์์ Code๋ .antMatchers("/xx").permitAll() ๊ณผ ๊ฐ์ด ์ธ์ฆ / ์ธ๊ฐ ์ฒ๋ฆฌ ์์ด ์ ๊ทผ์ด ๊ฐ๋ฅํ๊ฒ ํ๋ ์ค์ ๊ณผ ๋๊ฐ์์.
๋ค๋ง, ์ฐจ์ด์ ์ .antMatchers("/xx").permitAll()๋ ์ผ๋จ SecurityFilter ์์ ๋ค์ด์์ ์ฌ์ฌ๋ฅผ ๋ฐ๊ณ , ํต๊ณผ๋ฅผ ํ๊ฒ ์ฒ๋ฆฌํ๋๋ฐ, ์์ web.ignoring()์ ์์ SecurityFilter๋ฅผ ๊ฑฐ์น์ง ์๊ณ , ํต๊ณผ๊ฐ ๋ฉ๋๋ค.
๐ฝ Form ์ธ์ฆ
๐ฆ ์ด์ฉ์ ๋ฑ๋ก ๋ฐ PasswordEncoder
PasswordEncoder๋?
1. ๋น๋ฐ๋ฒํธ๋ฅผ ์์ ํ๊ฒ ์ํธํ(๋จ๋ฐฉํฅ - Hash ์ํธํ) ํ๋ ๊ธฐ๋ฅ ์ ๊ณต
2. Spring Security 5.0 ์ดํ์๋ ๊ธฐ๋ณธ PasswordEncoder๊ฐ ํ๋ฌธ์ ์ง์ํ๋ NoOpPasswordEncoder(ํ์ฌ๋ Deprecated)์์.
3. ์์ฑ
PasswordEncoder passwordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
โข ์ฌ๋ฌ๊ฐ์ PasswordEncoder ์ ํ์ ์ ์ธํ๊ณ , ์ํฉ์ ๋ง๊ฒ ์ ํํด์ ์ฌ์ฉํ ์ ์๋๋ก ์ง์ํ๋ Encoder.
4. ์ํธํ ํฌ๋งท : {id - Algorithm ์ข ๋ฅ}encodedPassword
โข ๊ธฐ๋ณธ ํฌ๋งท : Bcrypt - {bcrypt}$2a$10$dXJ3SW6G7P50IGmMkkmwe.20cQQubK3.HZWzG3YB1tlRy.fqvM/BG
โข Algorithm ์ข
๋ฅ : bcrypt, noop(ํ๋ฌธ), pbkdf2, scrypt, sha256, ๋ฑ๋ฑ..
5. Interface
โข encode(password).
- Password ์ํธํ.
โข matches(rawPassword, encodedPassword) ๊ฒฐ๊ณผ๊ฐ์ Boolean.
- ํ์๊ฐ์
์ ์ํธํ ๋์ด ์ ์ฅ๋ ์ด์ฉ์ Password์ Login ์ ์
๋ ฅ๋ Password๋ฅผ ์ํธํ ํ์ฌ ์๋ก ๊ฐ์์ง ๋น๊ต.

๋จผ์ ํ์์ด ๊ฐ์ ํ ๋, ๊ฐ์ ๋ด์ Entity๋ฅผ ์์ ๊ฐ์ด ๊ตฌ์ฑํด ์ฃผ์์ด์.

Client๊ฐ ํ์ ๊ฐ์
์ด๋ผ๋ ์์ฒญ์ ๋ณด๋ผ ๋, ์ด์ฉ์๊ฐ ๋ณด๋ธ ๊ฐ๋ค์ ๋ด์ ์์ฒญ DTO์์.

Controller์์.
24~27๋ฒ์งธ ์ค๊น์ง๋ ํด๋น ํ์ ๊ฐ์
Page ์ ์์ ์ํ API์ด๊ณ , 29 ~ 34๋ฒ์งธ๊น์ง๋ ์ค์ ๋ก Client์์ ์ด์ฉ์๊ฐ ํ์ ๊ฐ์
์ ์ํด ์
๋ ฅํ ๊ฐ์ DTO๋ก ๋ฐ์ ํ์ ๊ฐ์
์ ์ฒ๋ฆฌํ๋ API์์.

Service Interface์ ์์ ๊ฐ์ด ์ถ์ Method๋ฅผ ํ๋ ๋ง๋ค์ด ์ฃผ์๊ตฌ์.

์์ ๊ฐ์ด ๊ตฌํ์ฒด๋ฅผ ์์ฑํด ์ฃผ์์ด์.
24๋ฒ์งธ ์ค์ ๋ณด๋ฉด ์ด์ฉ์๊ฐ ์
๋ ฅํ Password๋ฅผ ์ํธํํด์ DataBase์ ์ ์ฅ์ ํด์ผํด์.
๊ฐ์์์๋ Controller์์ ๋น์ฆ๋์ค ๋ก์ง์ ๊ตฌํํ๋ ๋ฑ, ์ ๊ฐ ๋ฐฐ์ ๊ณ , ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ๊ณผ ๋ฌ๋ผ ๋ค๋ฅด๊ฒ ๊ตฌํ์ ํ์์ต๋๋ค.
์ด์ฉ์๊ฐ ์
๋ ฅํ Password๋ฅผ ๊บผ๋ด์ passwordEncoder๋ก ์ํธํ๋ฅผ ํ ๋ค ๋ค์ ํด๋น DTO์ ๋ฃ๋๋ก ํ์์ด์.
๋ํ Data Base ์ฒ๋ฆฌ๋ฅผ ์ํ JPA save()์ ๊ฐ์ ๋ฃ์๋๋ DTO๋ฅผ Entity๋ก ๋ณํํ์ฌ ๋ฃ์ด์ฃผ์์ต๋๋ค.
ํ์ ๊ฐ์
์ ๋ํ HTML Code๋ ์ฃผ๋ํ๋์ Git Hub์ ๋ฐฉ๋ฌธํ์๋ฉด ๋ง๋ ๋ณด์ค ์ ์์ต๋๋ค.

ํ์ ๊ฐ์
Page ์ ๊ทผ์ ์ด์ฉ์ ๋ชจ๋๊ฐ ๊ฐ๋ฅํด์ผ ํด์.
๊ทธ๋ ๊ธฐ ๋๋ฌธ์ 52๋ฒ์งธ ์ค์ฒ๋ผ root page์ ํ์๊ฐ์
page๋ ์ธ์ฆ / ์ธ๊ฐ ์ฒ๋ฆฌ ์์ด ์ ๊ทผ ๊ฐ๋ฅํ๊ฒ ์ฒ๋ฆฌํ์์ต๋๋ค.

์ค๋ฅธ์ชฝ ์์ ๋ณด์ด๋ 'ํ์ ๊ฐ์
'์ ๋๋ฌ๋ณผ๊ฒ์.

์ด๋ ๊ฒ ์ ์ ๊ทผ ๋ ๊ฒ์ ํ์ธํ ์ ์์ด์.

์์ ๊ฐ์ด ํ์ ๊ฐ์
์ ์งํ ํด ๋ณผ๊ฒ์.

ํ์ ๊ฐ์
์ด ์๋ฃ๋๋ฉด root page์ ์ด๋ํ๊ฒ ์ฒ๋ฆฌ๊ฐ ๋์๊ธฐ ๋๋ฌธ์ root Page๋ก ์ด๋ ๋์์ต๋๋ค.

Data Base์๋ ๊ฐ์ด ์ ์์ ์ผ๋ก ๋ค์ด๊ฐ์ด์.
๐ฆ CustomUserDetailsService
์ด๋ฒ์๋ SpringSeucrity๋ฅผ ์ด์ฉํ์ฌ ์ธ์ฆ ์ฆ, ๋ก๊ทธ์ธ ์ฒ๋ฆฌ๋ฅผ ๊ตฌํํด ๋ณด๋๋ก ํ ๊ฒ์.

๋จผ์ User ๊ฐ์ฒด๋ฅผ ์์ํ CustomUserDetails๋ฅผ ๋ง๋ค์ด ์ฃผ๊ณ ,
Memeber Entity๋ฅผ Member ๋ณ์๋ก ๋ฃ์ด ๋์์ด์.
๊ทธ๋ฐ ๋ค ์์ฑ์๋ฅผ ๋ง๋ค์ด์ ๋งค๊ฐ ๋ณ์๋ก ์ด์ฉ์์ ์ ๋ณด(username, password, age ๋ฑ)์ ๊ถํ ๋ชฉ๋ก์ ๋ฐ์ ์ ์๋๋ก ๋ง๋ค์ด ์ค ๋ค User ๊ฐ์ฒด์ ์ ๋ฌ ๋๋๋ก ๊ตฌํ์ ํ์์ด์.
๋์ค์ Member ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ ์ ์๋๋ก getter์ ํด๋น ๋ฉค๋ฒ ๋ณ์ ์ฒ๋ฆฌ๋ฅผ ํด ์ฃผ์์ต๋๋ค.

์ค์ ๋ก ์ธ์ฆ ์ฒ๋ฆฌ๋ฅผ ํ๊ธฐ ์ํ Service ๊ฐ์ฒด์์.
๋จผ์ UserDetailsService Interface๋ฅผ ๊ตฌํํ์ฌ UserRepository๋ฅผ ์ฃผ์
๋ฐ๋๋ก ํ๊ณ , Service Annotation์ผ๋ก Bean ๊ฐ์ฒด๋ก ๋ฑ๋กํ์์ด์.
๊ทธ๋ฐ ๋ค loadUserByusername()๋ฅผ ์ฌ์ ์ ํ์ฌ ์ค๋๋ค.
25๋ฒ์งธ ์ค์ ์ธ์ฆ ์์ฒญ์ ํ ์ด์ฉ์์ ID๊ฐ Data Base์ ์๋์ง ์ฐพ์์ ํด๋น ์ด์ฉ์ ์ ๋ณด๋ฅผ ๋ชจ๋ ๋ถ๋ฌ์ค๋๋ก ํ์์ด์.
์ด ๋, Null Safe ์ฒ๋ฆฌ๋ฅผ ์ํด Optional๋ก ๊ฐ์ธ ์ฃผ์์ต๋๋ค.

Repository์ findUsername() ์ถ์ Method๋ฅผ ๋ง๋ค์ด ์ด์ฉ์์ id๋ฅผ ๋ฐ๋๋ก ํ๊ณ , DB์์ ์กฐํ๋ ์ด์ฉ์ ์ ๋ณด๊ฐ Optional๋ก ๊ฐ์ธ์ ธ์ ๋ฐํ๋๋๋ก ์ฒ๋ฆฌ ํ์์ด์.

27 ~ 28๋ฒ์งธ ์ค์ Data Base์ ์ธ์ฆ ์์ฒญ ์ด์ฉ์ ID๊ฐ ์กด์ฌํ์ง ์์ผ๋ฉด UsernameNotFoundException์ด ๋ฐํ๋๋๋ก ์ฒ๋ฆฌํ์์ด์.
ํด๋น ID๊ฐ ์กด์ฌํ๋ค๋ฉด Optional๋ก ๊ฐ์ธ์ง ๊ฐ์ฒด๋ฅผ Member ๊ฐ์ฒด๋ก ํ์ด์ฃผ๊ณ , ๊ถํ ์ ๋ณด๋ฅผ ๋ฐ๊ธฐ ์ํด List๋ฅผ ์์ฑํด ์ฃผ์์ด์.
๊ทธ๋ฐ ๋ค ํด๋น List์ ์ด์ฉ์๊ฐ ๊ฐ์ง๊ณ ์๋ ๊ถํ ์ ๋ณด๋ฅผ ๋ฃ์ด์ฃผ์์ต๋๋ค.
๋ง์ง๋ง์ผ๋ก CustomUserDetails ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด ์ด์ฉ์์ ์ ๋ณด์ ๊ถํ ๋ชฉ๋ก์ ๋ฐํํ๋๋ก ํ์ฌ์ฃผ์์ต๋๋ค.

์์์๋ SpringSecurity 5.7 ์ด์๋ถํฐ ์ฌ์ฉํ์ง ๋ชปํ๋ WebSecurityConfigurerAdapter๋ฅผ ์์๋ฐ์ง ์๊ณ ํ๋ ๋ฐฉ๋ฒ์ผ๋ก ํ์๋๋ฐ, ์์์ ๋ง๋ UserDetails ๊ด๋ จ ์ฒ๋ฆฌ๋ฅผ SpringSecutiry๊ฐ ์ฒ๋ฆฌํ๋๋ก ํ๋ ๋ถ๋ถ์์ ์๋ฌด๋ฆฌ ์ฐพ์๋ ๋ฐฉ๋ฒ์ด ์์ด ์ด์ฉ ์ ์์ด ์์ ๊ฐ์ด ์ฒ๋ฆฌ๋ฅผ ํ์์ด์.
31 ~ 33๋ฒ์งธ ์ค์ AuthenticationManagerBuilder ๊ฐ์ฒด์ userDetailsService()์ ์ฃผ๋ํ๋์ด ๋ง๋ userDetailsService ๊ฐ์ฒด๋ฅผ ์ ๋ฌํด ์ฃผ์์ต๋๋ค.
์ด๋ฅผ ์ํด 23๋ฒ์งธ์ ํด๋น ๊ฐ์ฒด๋ฅผ ์ฃผ์
ํด ์ฃผ์์ด์.

Test๋ฅผ ์ํด manager์ user1 ์ด์ฉ์๋ก ํ์๊ฐ์
์ ํ์์ต๋๋ค.

Data Base์๋ ์ ์์ ์ผ๋ก ๊ฐ์ด ๋ค์ด ๊ฐ์ด์.

์ธ์ฆ ์์ฒญ์ ํด ๋ณผ๊ฒ์!

JPA๊ฐ ์ ์์ ์ผ๋ก ์ด์ฉ์ ์ ๋ณด๋ฅผ ์กฐํํ ๊ฑธ ํ์ธํ ์ ์์ต๋๋ค!

์ ์์ ์ผ๋ก Login ์ฒ๋ฆฌ๊ฐ ์๋ฃ ๋์์ด์!
๐ฆ CustomAuthenticationProvider
์์์ ์ฃผ๋ํ๋์ CostomUserDetailsService๋ฅผ ํตํด ์ด์ฉ์๊ฐ ์ธ์ฆ์ ์ ์์ ์ผ๋ก ์๋ฃํ๋ฉด ์ธ์ฆ ์ด์ฉ์ ์ ๋ณด๋ฅผ ๋ฐํํ๋๋ก ๊ตฌํ์ ํ์์ด์.
์ง๊ธ๋ถํฐ๋ CostomUserDetailsService๊ฐ ๋ฐํํ๋

CustomUserDetails ๊ฐ์ ๋ฐ์ ์ถ๊ฐ ๊ฒ์ฆ์ ์ฒ๋ฆฌํ๋ AuthenticationProvider ๊ตฌํ์ฒด๋ฅผ ๋ง๋ค์ด ์ธ์ฆ ์ฒ๋ฆฌ๊ฐ ๋๋๋ก ๊ตฌํํด ๋ณผ๊ฒ์.

์ต์ด AuthenticationProvider ๊ตฌํ์ฒด๋ฅผ ๋ง๋ค์ด์ฃผ๊ณ , ์์์ ๋ง๋ UserDetailService์ ์ํธํ๋ Password ๋น๊ต๋ฅผ ์ํด PasswordEncoder๋ฅผ ์ฃผ์
ํ์ฌ ์ฃผ์์ด์.
๊ทธ๋ฐ ๋ค์ authenticate()๋ฅผ ์ฌ์ ์ํ๋๋ฐ, ์ด Method๋ ์ธ์ฆ ๊ฐ์ฒด์ธ authentication์ ๋ฐ๋๋ก ๋์ด ์์ด์.
22 ~ 23๋ฒ์งธ ์ค์ ์ธ์ฆ ์์ฒญํ ์ด์ฉ์๊ฐ ์
๋ ฅํ ์ด์ฉ์ ID์ Password๋ฅผ ๊ฐ๊ฐ ๊บผ๋ด ๋ฐ๊ณ , userDetailsService ์์ loadUserByUsername() ์๊ฒ ์ ๋ฌ์ ํ์ฌ ์ฃผ์์ด์.

loadUserByUsername()์ ํด๋น ์ธ์ฆ ์์ฒญ ์ด์ฉ์๊ฐ ์ ๋ ฅํ ID๊ฐ Data Base์ ์ ์ฅ๋ ID์ ์ผ์นํ๋์ง ํ์ธํ๋ ์ญํ ์ ํ๊ณ ์์ด์.
์ด์ฉ์ ID๊ฐ ์กด์ฌํ๋์ง ํ๋จ์ ํ๊ณ , ์ ์ ์ฒ๋ฆฌ๊ฐ ๋์๋ค๋ฉด Provider์๊ฒ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํด ์ค๊ฑฐ์์.

์ด ๋ ๋ฐํ ๊ฐ์ฒด Type์ ์ฃผ๋ํ๋์ด ์์์ ๋ง๋ CustomUserDetails๋ก ๋ฐ๊ณ ์์ด์.
27 ~ 28๋ฒ์งธ ์ค์์ ์ด์ฉ์๊ฐ ์
๋ ฅํ Password์ Data Base์ ์ ์ฅ๋ Password์ ์ํธํ๋ ๊ฐ์ด ์ผ์นํ๋์ง ํ์ธํ๊ณ ์์ด์. ์ฒซ๋ฒ์งธ ๋งค๊ฐ๋ณ์์๋ ์ด์ฉ์๊ฐ ์
๋ ฅํ ๊ฐ์ ๋ฃ์ด์ฃผ๊ณ , ๋๋ฒ์งธ๋ Data Base์ ์ ์ฅ๋ ๊ฐ์ ๋ฃ์ด ์ฃผ์์ด์.
๋น๋ฐ๋ฒํธ๊ฐ ํ๋ ธ๋ค๋ฉด BadCredentialsException๊ณผ ํจ๊ป ์์ ๋ฌธ์์ด์ด ๊ฐ์ด ์ ๋ฌ๋ ๊ฒ์ด์์.
ํด๋น ์ด์ฉ์์ ๋น๋น๋ฒํธ๊ฐ ๋ง๋ค๋ฉด Token์ ํ๋ ๋ง๋ค์ด์ฃผ๊ฒ ๋๋๋ฐ, ์ด ๋, ์ด์ฉ์์ ๋ชจ๋ ์ ๋ณด๊ฐ ๋ด๊ธด Member ๊ฐ์ฒด๋ฅผ getter๋ก ๋ถ๋ฌ ๋ฃ์ด์ฃผ๊ณ , ์ด๋ฏธ ๋น๋ฐ๋ฒํธ๋ ์ด ์์ ๋ค์ด๊ฐ ์๊ธฐ ๋๋ฌธ์ Null๋ก ๋๋ฒ์งธ ๋งค๊ฐ ๋ณ์์ ์ ๋ฌ์ ํ๊ณ , ๋ง์ง๋ง์ผ๋ก ํด๋น ์ด์ฉ์์ ๊ถํ ๋ชฉ๋ก์ ์ ๋ฌํ์ฌ ๊ทธ ๊ฐ์ ๊ฐ์ง๊ณ , Token์ ์์ฑํ๊ฒ ํด์ค์.
supports()๋ authentication ๊ฐ์ฒด Type๊ณผ CustomAuthenticationProvider์์ ์ด์ฉํ๊ณ ์ ํ๋ Token ๊ฐ์ด ์ผ์นํ๋์ง ํ์ธํ๊ณ , ์ธ์ฆ ์ฒ๋ฆฌํด ์ฃผ๋ ์น๊ตฌ์์.
์ด์ ๊ธ : [Spring Boot] Spring Security Basic - Spring Security ์ฃผ์ ์ํคํ์ณ ์ดํดํ๊ธฐ
๋ค์ ๊ธ : [Stpring Boot] Spring Security ์ค์ ํ๋ก์ ํธ - ์ธ์ฆ ํ๋ก์ธ์ค Form ์ธ์ฆ ๊ตฌํ(2)

์คํ๋ง ์ํ๋ฆฌํฐ ์ธ ์ก์ :๋ณด์ ๊ธฐ์ด๋ถํฐ OAuth 2๊น์ง
COUPANG
www.coupang.com
"์ด ํฌ์คํ ์ ์ฟ ํก ํํธ๋์ค ํ๋์ ์ผํ์ผ๋ก, ์ด์ ๋ฐ๋ฅธ ์ผ์ ์ก์ ์์๋ฃ๋ฅผ ์ ๊ณต๋ฐ์ต๋๋ค."