網頁

2020/4/10

Spring Boot Security CSRF Session timeouts custom AccessDeniedHandler

Spring Boot Security 因Session連線過期(session timeout)而導致CSRF驗證失敗的自訂拒絕存取的處理方法如下。

範例環境:

  • Spring Boot 2.2.1.RELEASE

Spring Security開啟CSRF防護時其CSRF token預設是存在HttpSession

若Session過期會使存在裡面的CSRF Token也消失,所以下次請求經過CsrfFilter驗證時會因為找不到CSRF Token而丟出MissingCsrfTokenException例外;
而Session未過期只是請求中的CSRF Token與Session內存的CSRF Token不一致而無法通過驗證則是丟出InvalidCsrfTokenException例外。

而Spring Security預設對上述兩種CSRF驗證失敗都是透過AccessDeniedHandlerImpl返回403 Forbidden。若要對以上兩種情形自訂不同的處理,可自訂拒絕存取處理器來達成。

CustomAccessDeniedHandler

package com.abc.demo.config.security;

import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.csrf.MissingCsrfTokenException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class AcsPortalAccessDeniedHandler implements AccessDeniedHandler {

    @Override
    public void handle(
            HttpServletRequest request,
            HttpServletResponse response,
            AccessDeniedException accessDeniedException) throws IOException, ServletException {

        if (accessDeniedException instanceof MissingCsrfTokenException) {
            // Session timeout導致的CSRF驗證失敗的處理
        } else {
            // 一般的CSRF Token驗證失敗處理
        }

    }
}

參考:

沒有留言:

張貼留言