[Spring Boot] Spring Security ์‹ค์ „ ํ”„๋กœ์ ํŠธ - ์ธ์ฆ ํ”„๋กœ์„ธ์Šค Form ์ธ์ฆ(1)

2022. 8. 23. 08:08ใ†Back-End ์ž‘์—…์‹ค/Spring Framework

728x90
๋ฐ˜์‘ํ˜•

 

 

์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ ์ธ ์•ก์…˜:๋ณด์•ˆ ๊ธฐ์ดˆ๋ถ€ํ„ฐ 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 ๊ตฌ์กฐ๋Š” ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

Package Tree ๊ตฌ์กฐ

 

ConfigController

 

 

MessageController

 

 

 

๊ฐ•์˜์—์„œ ํƒ€์ž„๋ฆฌํ”„๋ฅผ ํ†ตํ•œ 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

 

 

 

์ดˆ๊ธฐ Spring Security user Password

 

์ด์ œ ์œ„์™€ ๊ฐ™์ด ์ธ์ฆ์„ ์‹œ๋„ํ•ด ๋ณผ๊ฒŒ์š”!



 

์ •์ƒ์ ์œผ๋กœ /home์— ์ ‘์†ํ•˜์˜€์Šต๋‹ˆ๋‹ค!

 

์ด๋ฒˆ์—๋Š” Momory์— ์ž„์‹œ๋กœ ์‚ฌ์šฉ๋  ์‚ฌ์šฉ์ž ๊ณ„์ • ์„ค์ •์„ ํ•ด๋ณผ๊ฒŒ์š”.


์œ„์™€ ๊ฐ™์ด ์„ธ ๋ช…์˜ ์ด์šฉ์ž๋ฅผ ์ž„์‹œ๋กœ ์ƒ์„ฑํ•ด ์ฃผ์—ˆ์–ด์š”.

์—ญ์‹œ WebSecurityConfigurerAdpter๋ฅผ ์ƒ์†ํ•ด์„œ ํ•˜๋Š” ๋ฐฉ์‹์ด ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ์œ„์™€ ๊ฐ™์ด ๊ณต์‹ ๋ฌธ์„œ์— ๋‚˜์™€ ์žˆ๋Š” ๋ฐฉ์‹๋Œ€๋กœ ์ง„ํ–‰ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

 

WebSecurityConfigure.java

 

์ด์ œ๋Š” ๊ถŒํ•œ ์„ค์ •์„ ํ•ด ์ฃผ์—ˆ์–ด์š”.

๋จผ์ € 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์—์„œ ํ•ด๋‹น ์ด์šฉ์ž๊ฐ€ ์ ‘๊ทผ ์—ฌ๋ถ€๋ฅผ ๊ฒ€์‚ฌํ•˜๊ฒŒ ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ, ์œ„ ์ž์›๋“ค์€ ๋ณด์•ˆ ์„ค์ •์ด ํ•„์š”๊ฐ€ ์—†๋Š” ์นœ๊ตฌ๋“ค์ด์—์š”.

๊ทธ๋ž˜์„œ ์œ„์™€ ๊ฐ™์ด ๋ณด์•ˆ ์„ค์ •์ด ํ•„์š” ์—†๋Š” ์„ค์ •์„ ์ถ”๊ฐ€ํ•ด์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

WebSecurityConfigure.java


์œ„์˜ 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๋ฅผ ์•”ํ˜ธํ™” ํ•˜์—ฌ ์„œ๋กœ ๊ฐ™์€์ง€ ๋น„๊ต.

 

Member.java

 

๋จผ์ € ํšŒ์›์ด ๊ฐ€์ž…ํ•  ๋•Œ, ๊ฐ’์„ ๋‹ด์„ Entity๋ฅผ ์œ„์™€ ๊ฐ™์ด ๊ตฌ์„ฑํ•ด ์ฃผ์—ˆ์–ด์š”.

 

AccountRequestDTO.java


Client๊ฐ€ ํšŒ์› ๊ฐ€์ž…์ด๋ผ๋Š” ์š”์ฒญ์„ ๋ณด๋‚ผ ๋•Œ, ์ด์šฉ์ž๊ฐ€ ๋ณด๋‚ธ ๊ฐ’๋“ค์„ ๋‹ด์€ ์š”์ฒญ DTO์—์š”.

 

UserController.java


Controller์—์š”.

24~27๋ฒˆ์งธ ์ค„๊นŒ์ง€๋Š” ํ•ด๋‹น ํšŒ์› ๊ฐ€์ž… Page ์ ‘์†์„ ์œ„ํ•œ API์ด๊ณ , 29 ~ 34๋ฒˆ์งธ๊นŒ์ง€๋Š” ์‹ค์ œ๋กœ Client์—์„œ ์ด์šฉ์ž๊ฐ€ ํšŒ์› ๊ฐ€์ž…์„ ์œ„ํ•ด ์ž…๋ ฅํ•œ ๊ฐ’์„ DTO๋กœ ๋ฐ›์•„ ํšŒ์› ๊ฐ€์ž…์„ ์ฒ˜๋ฆฌํ•˜๋Š” API์—์š”.

 



UserService.java


Service Interface์— ์œ„์™€ ๊ฐ™์ด ์ถ”์ƒ Method๋ฅผ ํ•˜๋‚˜ ๋งŒ๋“ค์–ด ์ฃผ์—ˆ๊ตฌ์š”.

UserServiceImpl.java

 


์œ„์™€ ๊ฐ™์ด ๊ตฌํ˜„์ฒด๋ฅผ ์ƒ์„ฑํ•ด ์ฃผ์—ˆ์–ด์š”.
24๋ฒˆ์งธ ์ค„์— ๋ณด๋ฉด ์ด์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ Password๋ฅผ ์•”ํ˜ธํ™”ํ•ด์„œ DataBase์— ์ €์žฅ์„ ํ•ด์•ผํ•ด์š”.

๊ฐ•์˜์—์„œ๋Š” Controller์—์„œ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ๊ตฌํ˜„ํ•˜๋Š” ๋“ฑ, ์ œ๊ฐ€ ๋ฐฐ์› ๊ณ , ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•๊ณผ ๋‹ฌ๋ผ ๋‹ค๋ฅด๊ฒŒ ๊ตฌํ˜„์„ ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

์ด์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ Password๋ฅผ ๊บผ๋‚ด์„œ passwordEncoder๋กœ ์•”ํ˜ธํ™”๋ฅผ ํ•œ ๋’ค ๋‹ค์‹œ ํ•ด๋‹น DTO์— ๋„ฃ๋„๋ก ํ•˜์˜€์–ด์š”.


๋˜ํ•œ Data Base ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•œ JPA save()์— ๊ฐ’์„ ๋„ฃ์„๋•Œ๋Š” DTO๋ฅผ Entity๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ๋„ฃ์–ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.

ํšŒ์› ๊ฐ€์ž…์— ๋Œ€ํ•œ HTML Code๋Š” ์ฃผ๋‹ˆํ•˜๋ž‘์˜ Git Hub์— ๋ฐฉ๋ฌธํ•˜์‹œ๋ฉด ๋งŒ๋‚˜ ๋ณด์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.



WebSecurityConfigure.java


ํšŒ์› ๊ฐ€์ž… Page ์ ‘๊ทผ์€ ์ด์šฉ์ž ๋ชจ๋‘๊ฐ€ ๊ฐ€๋Šฅํ•ด์•ผ ํ•ด์š”.

๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— 52๋ฒˆ์งธ ์ค„์ฒ˜๋Ÿผ root page์™€ ํšŒ์›๊ฐ€์ž… page๋Š” ์ธ์ฆ / ์ธ๊ฐ€ ์ฒ˜๋ฆฌ ์—†์ด ์ ‘๊ทผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•˜์˜€์Šต๋‹ˆ๋‹ค.





์˜ค๋ฅธ์ชฝ ์œ„์— ๋ณด์ด๋Š” 'ํšŒ์› ๊ฐ€์ž…'์„ ๋ˆŒ๋Ÿฌ๋ณผ๊ฒŒ์š”.



์ด๋ ‡๊ฒŒ ์ž˜ ์ ‘๊ทผ ๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด์š”.





์œ„์™€ ๊ฐ™์ด ํšŒ์› ๊ฐ€์ž…์„ ์ง„ํ–‰ ํ•ด ๋ณผ๊ฒŒ์š”.



ํšŒ์› ๊ฐ€์ž…์ด ์™„๋ฃŒ๋˜๋ฉด root page์— ์ด๋™ํ•˜๊ฒŒ ์ฒ˜๋ฆฌ๊ฐ€ ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— root Page๋กœ ์ด๋™ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.



Data Base์—๋„ ๊ฐ’์ด ์ •์ƒ์ ์œผ๋กœ ๋“ค์–ด๊ฐ”์–ด์š”.





        ๐Ÿ“ฆ CustomUserDetailsService

์ด๋ฒˆ์—๋Š” SpringSeucrity๋ฅผ ์ด์šฉํ•˜์—ฌ ์ธ์ฆ ์ฆ‰, ๋กœ๊ทธ์ธ ์ฒ˜๋ฆฌ๋ฅผ ๊ตฌํ˜„ํ•ด ๋ณด๋„๋ก ํ• ๊ฒŒ์š”.

CustomUserDetails.java

 

๋จผ์ € User ๊ฐ์ฒด๋ฅผ ์ƒ์†ํ•œ CustomUserDetails๋ฅผ ๋งŒ๋“ค์–ด ์ฃผ๊ณ ,

Memeber Entity๋ฅผ Member ๋ณ€์ˆ˜๋กœ ๋„ฃ์–ด ๋‘์—ˆ์–ด์š”.

๊ทธ๋Ÿฐ ๋’ค ์ƒ์„ฑ์ž๋ฅผ ๋งŒ๋“ค์–ด์„œ ๋งค๊ฐœ ๋ณ€์ˆ˜๋กœ ์ด์šฉ์ž์˜ ์ •๋ณด(username, password, age ๋“ฑ)์™€ ๊ถŒํ•œ ๋ชฉ๋ก์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค์–ด ์ค€ ๋’ค User ๊ฐ์ฒด์— ์ „๋‹ฌ ๋˜๋„๋ก ๊ตฌํ˜„์„ ํ•˜์˜€์–ด์š”.

๋‚˜์ค‘์— Member ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ๋„๋ก getter์™€ ํ•ด๋‹น ๋ฉค๋ฒ„ ๋ณ€์ˆ˜ ์ฒ˜๋ฆฌ๋ฅผ ํ•ด ์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.


UserDetailService.java


์‹ค์ œ๋กœ ์ธ์ฆ ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๊ธฐ ์œ„ํ•œ Service ๊ฐ์ฒด์—์š”.

๋จผ์ € UserDetailsService Interface๋ฅผ ๊ตฌํ˜„ํ•˜์—ฌ UserRepository๋ฅผ ์ฃผ์ž…๋ฐ›๋„๋ก ํ•˜๊ณ , Service Annotation์œผ๋กœ Bean ๊ฐ์ฒด๋กœ ๋“ฑ๋กํ•˜์˜€์–ด์š”.

๊ทธ๋Ÿฐ ๋’ค loadUserByusername()๋ฅผ ์žฌ์ •์˜ ํ•˜์—ฌ ์ค๋‹ˆ๋‹ค.

25๋ฒˆ์งธ ์ค„์— ์ธ์ฆ ์š”์ฒญ์„ ํ•œ ์ด์šฉ์ž์˜ ID๊ฐ€ Data Base์— ์žˆ๋Š”์ง€ ์ฐพ์•„์„œ ํ•ด๋‹น ์ด์šฉ์ž ์ •๋ณด๋ฅผ ๋ชจ๋‘ ๋ถˆ๋Ÿฌ์˜ค๋„๋ก ํ•˜์˜€์–ด์š”.

์ด ๋•Œ, Null Safe ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•ด Optional๋กœ ๊ฐ์‹ธ ์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.

UserRepository.java


Repository์— findUsername() ์ถ”์ƒ Method๋ฅผ ๋งŒ๋“ค์–ด ์ด์šฉ์ž์˜ id๋ฅผ ๋ฐ›๋„๋ก ํ•˜๊ณ , DB์—์„œ ์กฐํšŒ๋œ ์ด์šฉ์ž ์ •๋ณด๊ฐ€ Optional๋กœ ๊ฐ์‹ธ์ ธ์„œ ๋ฐ˜ํ™˜๋˜๋„๋ก ์ฒ˜๋ฆฌ ํ•˜์˜€์–ด์š”.

UserDetailService.java


27 ~ 28๋ฒˆ์งธ ์ค„์€ Data Base์— ์ธ์ฆ ์š”์ฒญ ์ด์šฉ์ž ID๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์œผ๋ฉด UsernameNotFoundException์ด ๋ฐ˜ํ™˜๋˜๋„๋ก ์ฒ˜๋ฆฌํ•˜์˜€์–ด์š”.

ํ•ด๋‹น ID๊ฐ€ ์กด์žฌํ•œ๋‹ค๋ฉด Optional๋กœ ๊ฐ์‹ธ์ง„ ๊ฐ์ฒด๋ฅผ Member ๊ฐ์ฒด๋กœ ํ’€์–ด์ฃผ๊ณ , ๊ถŒํ•œ ์ •๋ณด๋ฅผ ๋ฐ›๊ธฐ ์œ„ํ•ด List๋ฅผ ์ƒ์„ฑํ•ด ์ฃผ์—ˆ์–ด์š”.

๊ทธ๋Ÿฐ ๋’ค ํ•ด๋‹น List์— ์ด์šฉ์ž๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ถŒํ•œ ์ •๋ณด๋ฅผ ๋„ฃ์–ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.

๋งˆ์ง€๋ง‰์œผ๋กœ CustomUserDetails ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด ์ด์šฉ์ž์˜ ์ •๋ณด์™€ ๊ถŒํ•œ ๋ชฉ๋ก์„ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ํ•˜์—ฌ์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.


WebSecurityConfigure.java


์œ„์—์„œ๋Š” SpringSecurity 5.7 ์ด์ƒ๋ถ€ํ„ฐ ์‚ฌ์šฉํ•˜์ง€ ๋ชปํ•˜๋Š” WebSecurityConfigurerAdapter๋ฅผ ์ƒ์†๋ฐ›์ง€ ์•Š๊ณ  ํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ ํ–ˆ์—ˆ๋Š”๋ฐ, ์œ„์—์„œ ๋งŒ๋“  UserDetails ๊ด€๋ จ ์ฒ˜๋ฆฌ๋ฅผ SpringSecutiry๊ฐ€ ์ฒ˜๋ฆฌํ•˜๋„๋ก ํ•˜๋Š” ๋ถ€๋ถ„์—์„œ ์•„๋ฌด๋ฆฌ ์ฐพ์•„๋„ ๋ฐฉ๋ฒ•์ด ์—†์–ด ์–ด์ฉ” ์ˆ˜ ์—†์ด ์œ„์™€ ๊ฐ™์ด ์ฒ˜๋ฆฌ๋ฅผ ํ•˜์˜€์–ด์š”.

31 ~ 33๋ฒˆ์งธ ์ค„์— AuthenticationManagerBuilder ๊ฐ์ฒด์— userDetailsService()์— ์ฃผ๋‹ˆํ•˜๋ž‘์ด ๋งŒ๋“  userDetailsService ๊ฐ์ฒด๋ฅผ ์ „๋‹ฌํ•ด ์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.

์ด๋ฅผ ์œ„ํ•ด 23๋ฒˆ์งธ์— ํ•ด๋‹น ๊ฐ์ฒด๋ฅผ ์ฃผ์ž…ํ•ด ์ฃผ์—ˆ์–ด์š”.






Test๋ฅผ ์œ„ํ•ด manager์™€ user1 ์ด์šฉ์ž๋กœ ํšŒ์›๊ฐ€์ž…์„ ํ•˜์˜€์Šต๋‹ˆ๋‹ค.




Data Base์—๋Š” ์ •์ƒ์ ์œผ๋กœ ๊ฐ’์ด ๋“ค์–ด ๊ฐ”์–ด์š”.

 

 



์ธ์ฆ ์š”์ฒญ์„ ํ•ด ๋ณผ๊ฒŒ์š”!

 


JPA๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ์ด์šฉ์ž ์ •๋ณด๋ฅผ ์กฐํšŒํ•œ ๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค!



์ •์ƒ์ ์œผ๋กœ Login ์ฒ˜๋ฆฌ๊ฐ€ ์™„๋ฃŒ ๋˜์—ˆ์–ด์š”!

 

 

 

        ๐Ÿ“ฆ CustomAuthenticationProvider

์œ„์—์„œ ์ฃผ๋‹ˆํ•˜๋ž‘์€ CostomUserDetailsService๋ฅผ ํ†ตํ•ด ์ด์šฉ์ž๊ฐ€ ์ธ์ฆ์„ ์ •์ƒ์ ์œผ๋กœ ์™„๋ฃŒํ•˜๋ฉด ์ธ์ฆ ์ด์šฉ์ž ์ •๋ณด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ๊ตฌํ˜„์„ ํ•˜์˜€์–ด์š”.

์ง€๊ธˆ๋ถ€ํ„ฐ๋Š” CostomUserDetailsService๊ฐ€ ๋ฐ˜ํ™˜ํ•˜๋Š” 


CustomUserDetails ๊ฐ’์„ ๋ฐ›์•„ ์ถ”๊ฐ€ ๊ฒ€์ฆ์„ ์ฒ˜๋ฆฌํ•˜๋Š” AuthenticationProvider ๊ตฌํ˜„์ฒด๋ฅผ ๋งŒ๋“ค์–ด ์ธ์ฆ ์ฒ˜๋ฆฌ๊ฐ€ ๋˜๋„๋ก ๊ตฌํ˜„ํ•ด ๋ณผ๊ฒŒ์š”.


CustomAuthenticationProvider.java

 

์ตœ์ดˆ AuthenticationProvider ๊ตฌํ˜„์ฒด๋ฅผ ๋งŒ๋“ค์–ด์ฃผ๊ณ , ์œ„์—์„œ ๋งŒ๋“  UserDetailService์™€ ์•”ํ˜ธํ™”๋œ Password ๋น„๊ต๋ฅผ ์œ„ํ•ด PasswordEncoder๋ฅผ ์ฃผ์ž…ํ•˜์—ฌ ์ฃผ์—ˆ์–ด์š”.

๊ทธ๋Ÿฐ ๋‹ค์Œ authenticate()๋ฅผ ์žฌ์ •์˜ํ•˜๋Š”๋ฐ, ์ด Method๋Š” ์ธ์ฆ ๊ฐ์ฒด์ธ authentication์„ ๋ฐ›๋„๋ก ๋˜์–ด ์žˆ์–ด์š”.

22 ~ 23๋ฒˆ์งธ ์ค„์— ์ธ์ฆ ์š”์ฒญํ•œ ์ด์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ์ด์šฉ์ž ID์™€ Password๋ฅผ ๊ฐ๊ฐ ๊บผ๋‚ด ๋ฐ›๊ณ , userDetailsService ์•ˆ์— loadUserByUsername() ์—๊ฒŒ ์ „๋‹ฌ์„ ํ•˜์—ฌ ์ฃผ์—ˆ์–ด์š”.

 

 

loadUserByUsername()์€ ํ•ด๋‹น ์ธ์ฆ ์š”์ฒญ ์ด์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ID๊ฐ€ Data Base์— ์ €์žฅ๋œ ID์™€ ์ผ์น˜ํ•˜๋Š”์ง€ ํ™•์ธํ•˜๋Š” ์—ญํ• ์„ ํ•˜๊ณ  ์žˆ์–ด์š”.

์ด์šฉ์ž ID๊ฐ€ ์กด์žฌํ•˜๋Š”์ง€ ํŒ๋‹จ์„ ํ•˜๊ณ , ์ •์ƒ ์ฒ˜๋ฆฌ๊ฐ€ ๋˜์—ˆ๋‹ค๋ฉด Provider์—๊ฒŒ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•ด ์ค„๊ฑฐ์—์š”.

 



CustomAuthenticationProvider.java


์ด ๋•Œ ๋ฐ˜ํ™˜ ๊ฐ์ฒด 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

"์ด ํฌ์ŠคํŒ…์€ ์ฟ ํŒก ํŒŒํŠธ๋„ˆ์Šค ํ™œ๋™์˜ ์ผํ™˜์œผ๋กœ, ์ด์— ๋”ฐ๋ฅธ ์ผ์ •์•ก์˜ ์ˆ˜์ˆ˜๋ฃŒ๋ฅผ ์ œ๊ณต๋ฐ›์Šต๋‹ˆ๋‹ค."

 

728x90
๋ฐ˜์‘ํ˜•