Spring Security에서 CSRF 대책을 활성화하고 로그 아웃을 구현할 때주의 사항

개요



본 기사에서는 Spring Security에서 CSRF 대책을 유효하게 해 로그아웃을 구현했을 때에 빠지기 쉬운 에러와 그 대책에 대해 소개합니다.

동작 확인 환경


  • OS: macOS Mojave 10.14.2
  • Spring Boot version: 2.1.2.RELEASE

  • Spring Security에서 CSRF 대책을 실시하고 로그 아웃을 구현했을 때 빠지기 쉬운 오류



    Spring Security에서 CSRF 대책을 활성화한 상태에서 데이터를 POST로 보낼 때 CSRF 토큰 값을 보내야 합니다. Thymeleaf를 사용하면 form 태그에서 th:action을 사용하기만 하면 CSRF의 토큰 값을 자동으로 만들고 보냅니다.
    따라서 Spring Security와 Thymeleaf를 사용한 경우 CSRF 대책에는 기본적으로 form 태그로 th:action을 쓰는 것만으로 좋지만 링크를 사용하여 로그아웃을 구현할 때는 주의가 필요합니다.
    아무것도 생각하지 않고 로그 아웃을 GET로하면 404 오류가 발생합니다.
    Spring Security는 기본적으로 GET로 전송할 때 CSRF 토큰 검사를 수행하지 않지만 로그 아웃의 경우 GET로 전송할 때 CSRF 토큰 검사를 수행합니다. 그러나 GET으로 전송하면 토큰 값은 자동으로 생성되지 않습니다.
    따라서 GET에서 로그아웃을 수행하면 404 오류가 발생합니다. 예를 들면 다음과 같습니다.

      이하의 코드로 로그아웃을 구현합니다.
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>メインページ</title>
    </head>
    <body>
    メインページです。
    <a href="/logout">ログアウト</a>
    </body>
    </html>
    
    

    Spring Security에서는, 로그아웃의 링크처에 "/logout"를 지정하는 것만으로 로그아웃할 수 있습니다만, 이 상태로 로그아웃의 링크를 클릭하면, 404 에러가 발생해 버립니다.


    CSRF 대책을 실시했을 때의 로그아웃 구현



    로그아웃을 GET로 행했을 경우, CSRF 토큰치가 자동 작성되지 않고, 에러가 되어 버리기 때문에, javascript를 사용해 이하와 같이 로그아웃시의 메소드를 POST로 변경합니다.
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>メインページ</title>
    </head>
    <body>
    メインページです。
    <form th:action="@{/logout}" name="logout" method="POST">
        <a href="javascript:logout.submit()">ログアウト</a>
    </form>
    </body>
    </html>
    

    그러면 CSRF 대책을 활성화한 상태에서 링크에서 로그아웃할 수 있습니다.

    좋은 웹페이지 즐겨찾기