csrf
์ ๋ํ ๋ถ๋ถ์ Reiphiel
๋์ Spring Security๋ก CSRF ํ๋กํ
์
์ ์ฉ
๊ธ์์ ๊ฐ์ ธ์์ต๋๋ค.์ง์๊ณผ ๊ฟํ์ด ๋์ง๋ "๋ ์ดํผ์์ ๋ธ๋ก๊ทธ" ๋ฐฉ๋ฌธํ๊ธฐ
"Spring Security๋ก CSRF ํ๋กํ ์ ์ ์ฉ" ๊ธ ๋ณด๋ฌ๊ฐ๊ธฐ
Authentication
๋ก๊ทธ์ธAuthorization
๊ถํ
1 (Http Request)
๐2 (UsernamePasswordAuthentication Token)
:id
์pw
๋ฅผ ๋ถ๋ฆฌํ๊ณ ๊ทธ ๊ฐ๋ค์ ๊ฐ๊ณ ์๋ค.
3 (AuthenticationManager)
:1 (Http Request)
๊ณผ4 (AuthenticationProvider)
๋ฅผ ์ฐ๊ฒฐํด์ฃผ๋ ์ฝ์ผํธ ์ญํ3 (AuthenticationManager)
์ ์์๋ฐ์์ ๊ตฌํํ ๊ฒ์ดProviderManager
4 (AuthenticationProvider)
: ์ธ์ฆ ์ญํ ๐ ๋ก๊ทธ์ธ๊ณผ ๊ด๋ จ๋จ
5 (UserDetailsService)
: ๋ก๊ทธ์ธ์ฒ๋ฆฌ5 (UserDetailsService)
์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ ์น๊ตฌ๊ฐ ์ฒ๋ฆฌloaduserBy()
๋ฉ์๋๊ฐ ๊ผญ ์์ด์ผ ํ๋ค.loaduserBy()
๋ฉ์๋์๊ฒid
๋ฅผ ๋ฃ์ด์ค๋ค.4 (AuthenticationProvider)
๊ฐloaduserBy()
๋ฉ์๋๋ฅผ ํธ์ถํด์ฃผ๊ณ ๋์- ๊ฒฐ๊ตญ ๋์ด์ค๋ ํ์ ์
6 (UserDetails)
์ด๋ค.loaduserBy()
๋ฉ์๋๋ฅผ ํตํด์ ์ด๋ป๊ฒ ๋ก๊ทธ์ธ ์ฒ๋ฆฌ ํด์ค์ง ๋ก์ง์ ์ฌ๊ธฐ์ ์ ์ด์ค๋ค.
6 (UserDetails)
์ธํฐํ์ด์ค๋ฅผ ์์๋ฐ์ ํด๋์ค๊ฐ ์ฒ๋ฆฌํด์ฃผ๊ณ- ๊ฒฐ๊ณผ๋ฌผ์
7 (AuthenticationProvider)
๋ฒ์ผ๋ก,- ๊ทธ๋ฆฌ๊ณ
8 (AuthenticationManager)
์ผ๋ก,- ๊ทธ๋ฆฌ๊ณ
9 (AuthenticationFilter)
์ผ๋ก,- ๊ทธ๋ฆฌ๊ณ ์ต์ข ๊ฒฐ๊ณผ๊ฐ
10 (SecurityContextHolder)
๋ก ์จ๋ค.
- ์ฐ๋ฆฌ๋
6 (UserDetails)
๋ง ์ํ๋ฉด ๋๋ค.
10 (SecurityContextHolder)
์ด ํ์๋ฆฌํ์์#autheication
์ ๋ด๋นํ๋ค.- ํ์๋ฆฌํ์์
#autheication
์์getPrinciple()
ํ๋ฉด6 (UserDetails)
์ ๊ฐ์ฒด๊ฐ ์จ๋ค.
10 (SecurityContextHolder)
์ ์ธ์ฆ์ ๋ณด๋ฅผ ๊ฐ์ง๊ณ ์๋ค.
: ๋ก๊ทธ์ธ์ ์ฑ๊ณต ๋์ด์๋์ ์ฌ๋ถ- ํ์๋ฆฌํ๋ ์คํ๋ง์ด
10 (SecurityContextHolder)
์ ๋ฌผ์ด๋ณผ ์ ์๋ค.- ๊ทธ๋์ ์ต์ข ๊ฒฐ๊ณผ๊ฐ
10 (SecurityContextHolder)
์ผ๋ก ์ค๋ ๊ฒ์ด๋ค.
HttpSecurity csrf
- ์ต๊ทผ์
Java
๊ธฐ๋ฐ์ ์น ํ๋ก์ ํธ๋ ๋๋ถ๋ถSpring
(์คํ๋ง) ํ๋ ์์ํฌ ๊ธฐ๋ฐ์ผ๋ก ๊ตฌํ๋๊ธฐ ๋๋ฌธ์- ์์ฐ์ค๋ฝ๊ฒ
Spring Security
๋ฅผ ์ด์ฉํ์ฌ ๋ณด์๊ด๋ จ ๊ธฐ๋ฅ๋ค์ ๊ตฌํํ๊ฒ ๋ฉ๋๋ค.- ๊ทธ์ค
CSRF
(Cross Site Request Forgery
: ์ฌ์ดํธ ๊ฐ ์์ฒญ ์์กฐ)๋ ๊ฐ๋ฐ์ค์๋ ๋งค์ฐ ๊ท์ฐฎ์ ์กด์ฌ์ ๋๋ค.- ์น์์
CSRF
ํ๋กํ ์ ์ ๋ณด์ ๋์ฑ ์ผ๋ก ๊ฑฐ์ ํ์์ ์ผ๋ก ์๊ตฌ๋์ง๋ง- ๊ฐ๋ฐ ํธ์์ฑ ๋ฌธ์ ๋ก ๊ฐ๋ฐ์ค์๋ ์ ํ ์ ๊ฒฝ์ฐ์ง ์๊ฑฐ๋ ๋นํ์ฑํํด๋๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ด ์์ต๋๋ค.
- ๊ฒฐ๊ตญ์๋ ๋ณด์์ ๊ฒ์ ํตํด ์ง์ ๋ฐ๊ณ ์ผ๊ด์ ์ผ๋ก ์์ค์ฝ๋๋ฅผ ๋ณ๊ฒฝํฉ๋๋ค.
- ํ์ง๋ง ๊ธํ๊ฒ ๊ณ ์น ์ฝ๋๋ ํญ์(?) ๋ฌธ์ ๋ฅผ ์ผ์ผํต๋๋ค.
- ๋ํ ์ด์์ค์๋ ์๋ชป๋ ์์ ์ผ๋ก ๋ฐฐํฌํ์ ์์ธ๋ฅผ ๋ง๋๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ด ์์ต๋๋ค.
AntPathRequestMatcher
AntPathRequestMatcher
๋AntPathRequestMatcher
์ ์ค์ ํ ์์์ ๋ณด์- ํด๋ผ์ด์ธํธ๊ฐ ์์ฒญํ ์์์ ๋ณด๋ฅผ
- ์๋ก ๋น๊ตํด์ ์ฐธ์ธ์ง ๊ฑฐ์ง์ธ์ง ์๋ ค์ฃผ๋ ๊ธฐ๋ฅ์ ํ๋ ํด๋์ค
configure(AuthenticationManagerBuilder auth)
configure(AuthenticationManagerBuilder auth)
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetails).passwordEncoder(passwordEncoder());
}
- ์ ๋ ฅ๋ฐ์ ๊ฐ๊ณผ
DB
์ ๊ฐ์ ๋น๊ตํด์ ๋ก๊ทธ์ธ ์ฒ๋ฆฌ๋ฅผ ํ๋ค
POST
๋ก ๋ค์ด์จ ์์ด๋์ ๋น๋ฐ๋ฒํธ๋ ๋๊ฐ ์ฒ๋ฆฌํ ๊น์?UserDetailsService
์PasswordEncoder
๊ฐ ์ฒ๋ฆฌํ๋๋ก ์ ํด์ ธ ์์ต๋๋ค!
DB
์์ ์์ด๋๋ก ์ฌ์ฉ์ ์ ๋ณด๋ฅผ ์กฐํํ๋ค (=๋น๋ฐ๋ฒํธ ํฌํจ)- ์ ๋ ฅ๋ฐ์ ๋น๋ฐ๋ฒํธ๋ฅผ ์ธ์ฝ๋ฉํ๋ค
- ์ธ์ฝ๋ฉํ ๋น๋ฐ๋ฒํธ์ ์ฌ์ฉ์ ์ ๋ณด์ ๋น๋ฐ๋ฒํธ๋ฅผ ๋น๊ตํ๋ค
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/css/**", "/js/**", "/img/**", "/error", "favicon.ico", "/resources/**");
}
/error
: ์ฌ์ฉ์๋ง๋ค ์ฒ์ ๋ก๊ทธ์ธํ๊ณ ๋๋ฉด/error
์์ฒญ์ด ์ด๋๊ฐ์์ ์๊ฒจ์ ์ด๊ฒ์ ๋ฌด์ํ๋ผ๊ณ ํด์ ๊ทธ๋ฅ ์ฐ๋ ๊ฑฐ๋ค- ์ ํํ๊ฒ๋ ์ ๋ชจ๋ฅธ๋ค.
- ๊ทธ๋ฅ ์ด๋ ๊ฒ ์ฐ๋ฉด ์๋ฌ ์๋ฌ๋์ ์ด๋ค๊ณ ํ๋ค
favicon.ico
: ํฌ๋กฌ ๋ธ๋ผ์ฐ์ ๋title
์ ์๋ ํํ์ด์ง ๊ณ ์ ์ ์ด๋ชจ๋์ฝ์ ๊ผญ ๋ฌ๋ผ๊ณ ํด์ ์ค๊ฒ์ด๋ค
resources
๋ ๋์ค์๋ ๋บ๋ค ์ด ์์ฒญ์ ์ ์ฌ๊ฒ ๊ฐ๋ค๊ณ ํจ
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/css/**", "/js/**", "/img/**", "/error", "favicon.ico", "/resources/**");
}
"/resources/**"
์ฌ๊ธฐ์ ์คํ๋ฅผ ๋๊ธฐ ๋๋ฌธ์ด๋ค.