亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

springboot中怎么利用security自定義CSRF防御

發布時間:2021-07-29 15:37:31 來源:億速云 閱讀:401 作者:Leah 欄目:大數據

今天就跟大家聊聊有關springboot中怎么利用security自定義CSRF防御,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。

查看csrfFilter源碼,會先去HttpSessionCsrfTokenRepository.loadToken加載CsrfToken ,其實就是從session中獲取。

public CsrfToken loadToken(HttpServletRequest request) {
    HttpSession session = request.getSession(false);
    if (session == null) {
        return null;
    }
    return (CsrfToken) session.getAttribute(this.sessionAttributeName);
}

如果不存在,會創建一個CsrfToken 并放入session

public void saveToken(CsrfToken token, HttpServletRequest request, HttpServletResponse response) {
    if (token == null) {
        HttpSession session = request.getSession(false);
        if (session != null) {
            session.removeAttribute(this.sessionAttributeName);
        }
    } else {
        HttpSession session = request.getSession();
        session.setAttribute(this.sessionAttributeName, token);
    }
}

之后會從request中取token,與從session中取出的token對比,所以這里開啟csrf認證后,這四種請求是不驗證csrf的”GET”, “HEAD”, “TRACE”, “OPTIONS”,常用的POST請求,每次都要么在請求頭上加上X-CSRF-TOKEN:csrf值,或者在POST中加入參數_csrf:csrf值,這樣才能取出request中的csrf和session中的對比。

    String actualToken = request.getHeader(csrfToken.getHeaderName());
    if (actualToken == null) {
        actualToken = request.getParameter(csrfToken.getParameterName());
    }
    if (!csrfToken.getToken().equals(actualToken)) {
        if (this.logger.isDebugEnabled()) {
            this.logger.debug("Invalid CSRF token found for "
                    + UrlUtils.buildFullRequestUrl(request));
        }
        if (missingToken) {
            this.accessDeniedHandler.handle(request, response,
                    new MissingCsrfTokenException(actualToken));
        }else {
            this.accessDeniedHandler.handle(request, response,
                    new InvalidCsrfTokenException(csrfToken, actualToken));
        }
        return;
    }

如果request中取出的csrf和session中取出的不相等,會進入accessDeniedHandler.handle,這個accessDeniedHandler是AccessDeniedHandlerImpl,里面方法如下:

public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException)
throws IOException, ServletException {
    if(!response.isCommitted()) {
      if(this.errorPage != null) {
        request.setAttribute("SPRING_SECURITY_403_EXCEPTION", accessDeniedException);
        response.setStatus(403);
        RequestDispatcher dispatcher = request.getRequestDispatcher(this.errorPage);
        dispatcher.forward(request, response);
      } else {
        response.sendError(403, accessDeniedException.getMessage());
      }
    }
}

如果設置了errorPage會服務器內部轉發到該路徑,之后還是會經過security的各個filter進行登陸操作,最終登陸成功。這不是我要的,,所以需要自定義一個accessDeniedHandler。代碼如下,如果不是登陸請求的 csrf不匹配,都退出當前用戶,登陸用戶不做csrf校驗。

@Component
public class CsrfAccessDeniedHandler implements AccessDeniedHandler {
    private SecurityContextLogoutHandler logoutHandler = new SecurityContextLogoutHandler();
    @Autowired
    private AjaxLogoutSuccessHandler ajaxLogoutSuccessHandler;
    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException e)
	throws IOException, ServletException {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        logoutHandler.logout(request, response, auth);
        ajaxLogoutSuccessHandler.onLogoutSuccess(request, response, auth);
    }
}

然后在securityConfig里配置

@Override
protected void configure(HttpSecurity http) throws Exception {
    // 允許iframe
    http.headers().frameOptions().sameOrigin();
    //登陸頁面不做csrf校驗
    http.csrf().ignoringAntMatchers("/login");

    //異常處理
    http.exceptionHandling().
        accessDeniedHandler(csrfAccessDeniedHandler)
}

看完上述內容,你們對springboot中怎么利用security自定義CSRF防御有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

淮安市| 龙泉市| 锡林郭勒盟| 云霄县| 将乐县| 开阳县| 昭觉县| 左贡县| 霍州市| 宁晋县| 武宣县| 奉节县| 乌海市| 绍兴县| 田阳县| 周口市| 浦江县| 扶风县| 保康县| 托里县| 玛沁县| 九台市| 高尔夫| 得荣县| 焉耆| 沾化县| 广东省| 浦江县| 安龙县| 景泰县| 闵行区| 山丹县| 固始县| 澄迈县| 高邑县| 隆林| 理塘县| 开封县| 山西省| 曲水县| 来安县|