

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/**"์ฌ๊ธฐ์ ์คํ๋ฅผ ๋๊ธฐ ๋๋ฌธ์ด๋ค.