Spring/Spring 학습

[Spring Security] CSRF /logout 설정

HSY_mumu 2022. 10. 11. 17:19
728x90

1. CSRF 토큰 사용할 때

1) 스프링 시큐리티 설정 Java 코드

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@RequiredArgsConstructor
public class SecurityConfig {
    private final AuthenticationSuccessHandler authenticationSuccessHandler;
    private final AuthenticationFailureHandler authenticationFailureHandler;

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
                .formLogin(
                        formLogin -> formLogin
                                .loginPage("/member/login") // GET
                                .loginProcessingUrl("/member/login") // POST
                                .successHandler(authenticationSuccessHandler)
                                .failureHandler(authenticationFailureHandler)
                )
                .logout(
                        logout -> logout.logoutUrl("/member/logout")
                );

        return http.build();
    }
}

- 기본적으로 별다른 설정을 하지 않으면 CSRF 토큰을 사용하는 방식으로 시큐리티가 동작한다

 

2) HTML 코드

<a href="javascript: document.logoutForm.submit();" class="inline-flex" sec:authorize="isAuthenticated()">
    <i class="fa-solid fa-arrow-right-from-bracket"></i>
    <span class="ml-[2px] hidden sm:block">
        로그아웃
    </span>
</a>
<!--            CSRF 때문에 /member/logout POST로 요청-->
<form name="logoutForm" th:action="@{/member/logout}" method="post" hidden></form>

- POST /member/logout 요청을 보내기 위해 form 으로 전송한다

 

3) 실제 브라우저 HTML 코드

<a href="javascript: document.logoutForm.submit();" class="inline-flex">
    <i class="fa-solid fa-arrow-right-from-bracket"></i>
    <span class="ml-[2px] hidden sm:block">
        로그아웃
    </span>
</a>
<!--            CSRF 때문에 /member/logout POST로 요청-->
<form name="logoutForm" action="/member/logout" method="post" hidden><input type="hidden" name="_csrf" value="e1dfbb29-e4db-434f-9653-fb38ad65e503"/></form>

- form 태그에 csrf 토큰 값이 추가된 것을 확인할 수 있다.

 

2. CSRF 토큰 사용하지 않을 때

1) 스프링 시큐리티 설정 Java 코드

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@RequiredArgsConstructor
public class SecurityConfig {
    private final AuthenticationSuccessHandler authenticationSuccessHandler;
    private final AuthenticationFailureHandler authenticationFailureHandler;

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
                .formLogin(
                        formLogin -> formLogin
                                .loginPage("/member/login") // GET
                                .loginProcessingUrl("/member/login") // POST
                                .successHandler(authenticationSuccessHandler)
                                .failureHandler(authenticationFailureHandler)
                )
                .logout(
                        logout -> logout.logoutUrl("/member/logout")
                )
                .csrf().disable(); // CSRF 토큰 끄기;

        return http.build();
    }
}

- csrf().disable() 로 CSRF 토큰을 발행하지 않도록 설정한다

 

2) HTML 코드

<a href="/member/logout" class="inline-flex" sec:authorize="isAuthenticated()">
    <i class="fa-solid fa-arrow-right-from-bracket"></i>
    <span class="ml-[2px] hidden sm:block">
        로그아웃
    </span>
</a>

- form 으로 POST 요청을 보낼필요 없이 GET /member/logout 요청을 보내도 잘 동작한다.

 

정리

- logout() 으로 로그아웃 처리가 가능하다

- CSRF 토큰을 사용할 때반드시 POST 방식으로 로그아웃을 처리한다

- CSRF 토큰을 사용하지 않을 때는 GET 방식으로도 로그아웃 처리가 가능하다

 

https://velog.io/@wnsqud70/CSRFlogOut%EC%84%A4%EC%A0%95

 

CSRF/logOut설정

스프링 시큐리티는 기본적으로 CSRF(크로스 사이트 요청 위조) 라는 공격을 방어하기 위해서 임의의 값을 만들어서 이를 GET방식을 제외한 모든 요청방식(POST,PUT,DELETE)등에 포함시켜야만 정상적인

velog.io

 

728x90