[Spring] Spring Security(์คํ๋ง ์ํ๋ฆฌํฐ) CSRF, CsrfFilter - ๋ก๊ทธ์์ ์์
๊ณต๊ฒฉ์ ์ํ์ฑ
ํด๋น ๋ก์ง์ ํตํด์ ํด์ปค๋ค์ด ๊ณต๊ฒฉ์ ํ๋ค.
- ์ฌ์ฉ์๊ฐ ์ผํ๋ชฐ์ ๋ก๊ทธ์ธํ๊ณ ๋์ ์ฟ ํค๋ฅผ ๋ฐ๊ธํ๋ฉด ์ฌ์ฉ์์ ๋ธ๋ผ์ฐ์ ์ ์ฟ ํค๊ฐ ์ ์ฅ๋๋ค.
- ๊ณต๊ฒฉ์๊ฐ ๋งํฌ๋ฅผ ์ด์ฉ์์๊ฒ ์ ๋ฌํ๊ณ ์ฌ์ฉ์๋ ๋งํฌ๋ฅผ ํด๋ฆญํด์ ๊ณต๊ฒฉ์ฉ ์นํ์ด์ง์ ์ ์ํ๋ค.
- ๋ธ๋ผ์ฐ์ ๋ ์ด๋ฏธ์ง ํ์ผ์ ๊ฐ์ ธ์ค๊ธฐ ์ํด์ ๊ณต๊ฒฉ์ฉ url์ ์ด๊ณ ์ผํ๋ชฐ์ ํด๋น ์ฟ ํค๋ฅผ ๊ฐ์ง ๋ธ๋ผ์ฐ์ ๋ฅผ ์์ฌํ์ง ์๊ณ ์ธ์ฆ์ ํ๋ค.
์ํ๋ฆฌํฐ๋ ์ด๋ฐ ๊ณต๊ฒฉ ๋ฐฉ์์ ๋ฐฉ์ดํ๊ธฐ ์ํด์ CsrfFilter๋ฅผ ๋ง๋ค์ด์ csrf์ ์ทจ์ฝ์ ์ ๋ฐฉ์งํ๊ณ ์๋ค.
CsrfFilter
- ๋ชจ๋ ์์ฒญ์ ๋๋ค ํ๊ฒ ์์ฑ๋ ํ ํฐ์ HTTP ํ๋ผ๋ฏธํฐ๋ก ์๊ตฌ
- ์์ฒญ ์ ์ ๋ฌ๋๋ ํ ํฐ ๊ฐ๊ณผ ์๋ฒ์ ์ ์ฅ๋ ์ค์ ๊ฐ๊ณผ ๋น๊ตํ ํ ๋ง์ฝ ์ผ์นํ์ง ์์ผ๋ฉด ์์ฒญ์ ์คํจํจ
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
HTTP ๋ฉ์๋ : PATCH, POST, PUT, DELETE ์ฌ์ฉํ ๊ฒฝ์ฐ์๋ ํด๋น csrf ํ ํฐ์ hidden์ผ๋ก ์ฒ๋ฆฌํด์ ์ธ์ฆํ ์ ์๋๋ก ํด์ผ ๋จ → ์ ๊ทธ๋ฌ๋ฉด accessDeniedHandler์ ๊ฑธ๋ ค์ ์ ์ํ์ง ๋ชปํ๋๋ก ์ฒ๋ฆฌํจ
- form๋ฐฉ์์ผ๋ก ํ ๊ฑฐ๋ฉด formํ๊ทธ ์์ ์ด๋ ๊ฒ ์์ฑํด์ผ ์ ์์ ์ผ๋ก ์๋๋๋ค.
โ ์คํ๋ง ์ํ๋ฆฌํฐ๋ ๊ธฐ๋ณธ์ ์ผ๋ก ํ์ฑํ๋์ด ์์ผ๋ฉฐ ์๋ ์ฝ๋๋ฅผ ์ถ๊ฐํ๋ฉด ๋นํ์ฑํ๋๋ค.
http.csrf().disabled() // ๋นํ์ฑํ
Post ๋ฐฉ์ ์ฌ์ฉ ์์
๋ก๊ทธ์์์ ํผํ๊ทธ ์์์ ์ฌ์ฉํด์ผ ๋๋ค.
html
<form class="logout" id="logout" th:action="@{/logout}" method="POST">
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
</form>
javascript
document.getElementById('logoutBtn').addEventListener('click', function (){
document.getElementById('logout').submit();
});
SecurityConfig
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/login")
ํด๋น ๊ธ์ ์ธํ๋ฐ์ ์คํ๋ง์ํ๋ฆฌํฐ-Spring Boot ๊ธฐ๋ฐ์ผ๋ก ๊ฐ๋ฐํ๋ Spring Security๋ฅผ ๋ณด๊ณ ์์ฑํ ๊ธ์ ๋๋ค.