Spring Security
package com.todolist.todo;
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.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
public class springSecurityTest extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
super.configure(auth);
}
@Override
public void configure(WebSecurity web) throws Exception {
// super.configure(web);
// ACL(Access Control List - ์ ๊ทผ ์ ์ด ๋ชฉ๋ก)์ ์์ธ URL์ ์ค์
web.ignoring().antMatchers("/assets/**"); // ์ด๋ฏธ์ง ๊ฒฝ๋ก๋ก ๋ค์ด์ค๋ ๊ฒฝ๋ก
web.ignoring().antMatchers("/favicon.ico"); // favicon.ico๋ ๊ฐ๋ฅํ๊ฒ
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// super.configure(http); // ๋ชจ๋ URL์ ๋ง๊ณ ์๋ ์ํฉ
http.authorizeRequests()
.antMatchers("/users/logout").authenticated()
.antMatchers("/board/write", "/board/delete", "/board/modify").authenticated()
.antMatchers("/admin/**").hasAuthority("ROLE_ADMIN")
.anyRequest().permitAll();
}
}
์์ ๊ฐ์ ํํฐ๋ฅผ ์ ์ฉํ์ฌ Spring Security๋ฅผ ๊ธฐ๋ณธ์ ์ผ๋ก ์ค์ ํด์ฃผ๊ณ ์์ต๋๋ค.
์ฒ์์๋ localhost๋ก ์ ๊ทผํ์ ๋, ๋ค์ด๊ฐ์๋ง์ ๊ณ์ login์ผ๋ก ๋์ด๊ฐ์๋๋ฐ์. ์์ ์ค์ ์ ์ ์ฉํด์ฃผ๊ณ ๋๋ ์ด์ ์ค์ ๋ ๋ถ๋ถ(authenticated๋ ๋ถ๋ถ)์ ๋ค์ด๊ฐ์ง์ง ์๊ณ , ๊ทธ ์ธ์ ๊ฒ๋ค์ ์ ๋ค์ด๊ฐ์ง๋๋ค.
package com.todolist.todo.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MainController {
@RequestMapping("/login")
public String hello() {
return "Hello World!";
}
@RequestMapping("/test")
public String test() {
return "It's test page";
}
@RequestMapping("/users/logout")
public String logout() {
return "logout";
}
}
Whitelabel Error Page๋ผ๊ณ ๋จ๋๊ฒ ์ ์์ธ์ง๋ ์ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค. ์ ๋ ์ url๋ก ์ ์ํ๋ฉด login ํ์ด์ง๊ฐ ๋ค์ ๋จ๊ฒ๋ ๋ฐ๊พธ์ด์ฃผ๊ณ ์ถ์ต๋๋ค.
http.csrf().disable();
๊ทธ๋ค์์ ์ ๋ด์ฉ์ ๊ธฐ์ ํ์๋๋ฐ, CSRF๊ฐ ๋ญ์ง ๋ชฐ๋ผ์ ์ฐพ์๋ณด๋, Cross Site Request Forgery ๊ณต๊ฒฉ์ ์คํ๋ง ์ํ๋ฆฌํฐ ์ธก์์ ์ฐจ๋จํ๋ ์ฝ๋๊ฐ ์กด์ฌํ๋๋ฐ, ์ด๋ฅผ disableํ๋ ๊ฒ์ด ์๋๊ฐ ์ถ์ต๋๋ค. (์๋๋๋ก์ ํด๊ฒฐ์ CORS๋ฅผ ์ํด, ์ ๊ทผ ๊ฐ๋ฅํ ํ์ด์ง๋ฅผ ์์ธํ๊ฒ ์ ๋ฆฌํด์ผ๊ฒ ์ฃ ?)
๋ก๊ทธ์ธ ์ค์ ๋์ค ์๋ฌ ๋ฐ์
// 2. ๋ก๊ทธ์ธ ์ค์
http
.formLogin()
.loginPage("user/login") // ๋ก๊ทธ์ธ ํ์ด์ง URL
.loginProcessingUrl("/user/auth")
.failureUrl("/user/login?result=fail")
.defaultSuccessUrl("/", true)
.usernameParameter("email") // ๋ก๊ทธ์ธ ์์ฒญ ์ id์ฉ ํ๋ผ๋ฏธํฐ. email, id, name ๋ฑ ๋ฌด์๋ ์๊ด ์๋ค๊ณ ํ๋ค.
.passwordParameter("password");
Error creating bean with name 'springSecurityFilterChain'
์ด๋ผ๋ ์ด๋ฆ์ ์๋ฌ ๋ฐ์. ํด๊ฒฐํ๊ธฐ ์ํด ์๋ฌ ์ด๋ฆ ๊ฒ์ํด๋ณด๋ ์คํ์ค๋ฒํ๋ก์ฐ์์ ํด๋น ๊ฒ์๊ธ์ ๋ฐ๊ฒฌํจ.
- ์๋1. getter์ setter๊ฐ ๋ชจ๋ ์ ๋ค์ด์๋์ง? : ์ ๋ค์ด์์์.
- ์๋ 2. http.antMatchers(โโ) ์์ ์๋ฌ๊ฐ ๋ฐ์ํ ์๋ ์๋ค๊ณ ํจ. ์๋ํ๋ฉด SpringSecurityFilterChanin์ ํจํด์ด empty/null์ด๋ฉด ์๋ฌ๋ฅผ ๋ฐ์์ํค๊ธฐ ๋๋ฌธ์. -> ๋ด ์ฝ๋์๋ ๊ทธ๋ฐ ๋ด์ฉ์ ์์์ง๋ง, SpringSecurityFilterChain์ด ๋ฌธ์ ์ธ ๋ฏ ํ์ฌ ๊ผผ๊ผผํ๊ฒ ํํฐ์ฒด์ธ ๋ถ๋ถ๋ค์ ์ฝ์ด๋ณด๋
/user/login
์ผ๋ก ์ ํ์ด์ผ ํ๋ ๋ถ๋ถ์ดuser/login
์ผ๋ก ์ ํ์์์. ์๋ฌด๋๋ ๊ทธ๋ฌ๋ฉด ์กด์ฌํ ์ ์๋ url์ด๋ผ ์๋ฌ๊ฐ ๋ฐ์ํ๋ฏ? ๊ณ ์น๋๊น ์ ๋์๊ฐ๋ค.
H2 ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ถ๊ฐ
H2๋ฅผ ์ถ๊ฐํด์ ์ฌ์ฉํ๋ ค๊ณ ํ๋ Spring Security ๊ณต์ ๋ฉ๋ด์ผ์์๋ ๋ค์๊ณผ ๊ฐ์ Configruation์ ์์ ํด๋ฌ๋ผ๊ณ ใ ๋๋ค.
- Allow all access to the url path /console/*
- Allow all requests to the root url
- Disable CRSF
- Disable X-Frame-Options in Spring Security
์๋ ๊ฒ ํด์ฃผ๋ฉด ๋๋ค๊ณ ํ๋ค.
๊ทธ๋ฆฌ๊ณ application.properties
์ ๋ค์๊ณผ ๊ฐ์ ์ค์ ์ ๋ฃ์ด์ค๋๋ค.
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
์ฌ์ค h2-console์ด ๋ํดํธ๋ผ๊ณ ํ๊ธฐ๋ ํ๋๋ฐ, ์ ์ด์ ์ ์ฝ์ ๊ณต์๋ฌธ์์์๋ console๋ก ์ ์ํ๋ผ๊ณ ํด์โฆ ํน์ ๋ชจ๋ฅด๋ h2-console์ด๋ผ๊ณ ์ง์ ํด์ฃผ์๋๋ค. ์ด๋ ๊ฒ ํด์ฃผ๊ณ ๋ค์ ํ๋ก์ ํธ๋ฅผ ๋ฐํด๋ณด๋ฉด,
์๋ ๊ฒ ๋ฑ ๋น๋๋ค. ์ฐ๊ฒฐ ์ค์ ์ ์ํด์๋ ํด๋น ๊ฒ์๊ธ์ ์ฐธ๊ณ ํ์ต๋๋ค.
๋ค์ ์ ๋์์ต๋๋ค.
DAO๋ฅผ ์์ฑํ๋ ค๋ jpa๋ฅผ gradle์ ์ต์ด์ ๋ฃ์ง ์์ ๊ฒ์ ๋ฐ๊ฒฌํด ๋ฃ์ด์ค๋๋ค. (๋ฃ์ด์ฃผ์ ํ์๋ ๊ผญ refresh ํด์ฃผ์ ์ผํฉ๋๋ค.)
์ถ๊ฐ ๊ณต๋ถ
CSRF
- CSRF : Cross Site Request Forgery. ์ธํฐ๋ท ์ฌ์ฉ์๊ฐ ์์ ์ ์์ง์๋ ๋ฌด๊ดํ๊ฒ ๊ณต๊ฒฉ์๊ฐ ์๋ํ ํ์(์์ , ์ญ์ ๋ฑ๋ก ๋ฑ)๋ฅผ ํน์ ์น์ฌ์ดํธ์ requestํ๊ฒ ๋ง๋๋ ๊ณต๊ฒฉ
- ํฌ์์์ ๊ถํ์ ๋์ฉํ๊ณ ์ค์ ๊ธฐ๋ฅ์ ์คํํ๊ฒ ํจ. (ex. ํ์ด์ค๋ถ ํฌ์์์ ๊ณ์ ์ผ๋ก ๊ด๊ณ ์ฑ ๊ธ ์ฌ๋ฆฌ๊ธฐ)
CSRF์ ๋ํ ๋ฐฉ์ด
- Referrer ๊ฒ์ฆ : ๋ฐฑ์๋ ๋จ์์ request์ด referrer์ ํ์ธํ์ฌ ๋๋ฉ์ธ์ด ์ผ์นํ๋์ง ๊ฒ์ฆ. (๋๋ถ๋ถ์ ๋ฐฉ์ดํ ์ ์๋ค.)
- Referrer : A ์ฌ์ดํธ์์ ๋งํฌ๋ฅผ ํด๋ฆญํ์ฌ B ์ฌ์ดํธ๋ก ์ด๋ํ๋ ๊ฒฝ์ฐ, ์น๋ธ๋ผ์ฐ์ ๋ B ์ฌ์ดํธ์ ํ์ด์ง์ ๋ํ ์์ฒญ์ ๋ณด๋ด๋ฉด์ HTTP ํค๋์ A์ฌ์ดํธ์ URL์ ๊ฐ์ด ์ค์ด ๋ณด๋ธ๋ค. ์ด๋ฌํ URL์ Referrer์ด๋ผ๊ณ ๋ถ๋ฆ. (๋ค๋ก ๊ฐ๊ธฐ๋ฅผ ๋๋ ์ ๋ ์ด์ ์ฌ์ดํธ๊ฐ ์ ์ฅ๋๋ ์๋ฆฌ์ธ ๊ฒ ๊ฐ๋ค.)
- Security Token ์ฌ์ฉ (CSRF Token) : ์ฌ์ฉ์ ์ธ์
์ ์์์ ๋์ ๊ฐ์ ์ ์ฅํ๊ณ , ์ฌ์ฉ์์ ์์ฒญ๋ง๋ค ํด๋น ๋์ ๊ฐ์ ํฌํจ์์ผ ์ ์กํจ.
- Double Submit Cookie ๊ฒ์ฆ : Security Token์ ํ ์ข
๋ฅ๋ก ์ธ์
์ ์ฌ์ฉํ ์ ์๋ ํ๊ฒฝ์์ ์ฌ์ฉ. ์น ๋ธ๋ผ์ฐ์ ์ Same Origin ์ ์ฑ
์ผ๋ก ์ธํด ์๋ฐ์คํฌ๋ฆฝํธ์์ ํ ๋๋ฉ์ธ์ ์ฟ ํค๊ฐ์ ํ์ธ/์์ ํ์ง ๋ชปํ๋ ๊ฒ์ ์ด์ํ ๋ฐฉ์ด ๊ธฐ๋ฒ์ด๋ค. ์๋ฒ๋จ์์๋ ์ฟ ํค์ ํ ํฐ ๊ฐ๊ณผ ํ๋ผ๋ฏธํฐ์ ํ ํฐ ๊ฐ์ด ์ผ์นํ๋ ์ง๋ง ๊ฒ์ฌํ๋ฉด ๋จ.
- Same-Origin Policy ๋์ผ ์ถ์ฒ ์ ์ฑ : ์ด๋ค ์ถ์ฒ์์ ๋ถ๋ฌ์จ ๋ฌธ์๋ ์คํฌ๋ฆฝํธ๊ฐ ๋ค๋ฅธ ์ถ์ฒ์์ ๊ฐ์ ธ์จ ๋ฆฌ์์ค์ ์ํธ์์ฉํ๋ ๊ฒ์ ์ ํํ๋ ๋ณด์ ๋ฐฉ์. ํ๋กํ ์ฝ, ํธ์คํธ, ํฌํธ๊ฐ ๋์ผํ ์๋ฒ๋ก๋ง ajax ์์ฒญ์ ์ฃผ๊ณ ๋ฐ์ ์ ์๋๋ก ํ๋ ์ ์ฑ ์ ์๋ฏธํ๋ค.
- CORS(Cross-Origin Resource Sharing) : ์ถ๊ฐ HTTP ํค๋๋ฅผ ์ฌ์ฉํ์ฌ ๋ธ๋ผ์ฐ์ ๊ฐ ํ ์ถ์ฒ์์ ์คํ์ค์ธ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ์ ํ๋ ์ก์ธ์ค ๊ถํ์ ๋ถ์ฌํ๋๋ก ํ๋ ๋งค์ปค๋์ฆ. ์์ฒด์ ๋ค๋ฅธ ์ถ์ฒ(๋๋ฉ์ธ, ํ๋กํ ์ฝ, ํฌํธ)๋ฅผ ๊ฐ์ง ๋ฆฌ์์ค๋ฅผ ์์ฒญํ ๋ cross-origin HTTP ์์ฒญ์ ์คํํจ. (Same-Origin Policy์ ๋ฌธ์ ์ ์ ํด๊ฒฐํ๊ธฐ ์ํ ์ ์ฑ ). ์ถ์ฒ๊ฐ ๋ค๋ฅธ ๋๋ฉ์ธ์์์ ajax์์ฒญ์ด๋๋ผ๋ ์๋ฒ ๋จ์์ ๋ฐ์ดํฐ ์ ๊ทผ ๊ถํ์ ํ์ฉํ๋ ์ ์ฑ
- CORS๋ ํ๋ก์ ํธ๋ฅผ ํ๋ฉด์ ํ ๋ฒ ๊ฒช์๋ ๋ฌธ์ ์. FE ์๋ฒ ๋จ๊ณผ BE ์๋ฒ ๋จ์ด ๋ค๋ฅด๋ค๋ณด๋ CORS๊ฐ ๋ฐ์ํ๋ฉด์ FE์์ BE ์๋ฒ์ ์์ฒญ์ ๋ณด๋ด์ง ๋ชปํ๋ ์ผ์ด ๋ฐ์ํ์์. ์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ์ฃผ๋จน๊ตฌ๊ตฌ ํด๊ฒฐ์ฑ ์ ์ฌ์ฉํ์ฌ ๋ชจ๋ ๋๋ฉ์ธ์ ์ด์ด๋์์๋ค.. ใ ใ ;
- Double Submit Cookie ๊ฒ์ฆ : Security Token์ ํ ์ข
๋ฅ๋ก ์ธ์
์ ์ฌ์ฉํ ์ ์๋ ํ๊ฒฝ์์ ์ฌ์ฉ. ์น ๋ธ๋ผ์ฐ์ ์ Same Origin ์ ์ฑ
์ผ๋ก ์ธํด ์๋ฐ์คํฌ๋ฆฝํธ์์ ํ ๋๋ฉ์ธ์ ์ฟ ํค๊ฐ์ ํ์ธ/์์ ํ์ง ๋ชปํ๋ ๊ฒ์ ์ด์ํ ๋ฐฉ์ด ๊ธฐ๋ฒ์ด๋ค. ์๋ฒ๋จ์์๋ ์ฟ ํค์ ํ ํฐ ๊ฐ๊ณผ ํ๋ผ๋ฏธํฐ์ ํ ํฐ ๊ฐ์ด ์ผ์นํ๋ ์ง๋ง ๊ฒ์ฌํ๋ฉด ๋จ.