今天就跟大家聊聊有關(guān)springboot中怎么利用security自定義CSRF防御,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。
創(chuàng)新互聯(lián)專(zhuān)注于未央網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗(yàn)。 熱誠(chéng)為您提供未央營(yíng)銷(xiāo)型網(wǎng)站建設(shè),未央網(wǎng)站制作、未央網(wǎng)頁(yè)設(shè)計(jì)、未央網(wǎng)站官網(wǎng)定制、成都微信小程序服務(wù),打造未央網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供未央網(wǎng)站排名全網(wǎng)營(yíng)銷(xiāo)落地服務(wù)。
查看csrfFilter源碼,會(huì)先去HttpSessionCsrfTokenRepository.loadToken加載CsrfToken ,其實(shí)就是從session中獲取。
public CsrfToken loadToken(HttpServletRequest request) { HttpSession session = request.getSession(false); if (session == null) { return null; } return (CsrfToken) session.getAttribute(this.sessionAttributeName); }
如果不存在,會(huì)創(chuàng)建一個(gè)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); } }
之后會(huì)從request中取token,與從session中取出的token對(duì)比,所以這里開(kāi)啟csrf認(rèn)證后,這四種請(qǐng)求是不驗(yàn)證csrf的”GET”, “HEAD”, “TRACE”, “OPTIONS”,常用的POST請(qǐng)求,每次都要么在請(qǐng)求頭上加上X-CSRF-TOKEN:csrf值,或者在POST中加入?yún)?shù)_csrf:csrf值,這樣才能取出request中的csrf和session中的對(duì)比。
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中取出的不相等,會(huì)進(jìn)入accessDeniedHandler.handle,這個(gè)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()); } } }
如果設(shè)置了errorPage會(huì)服務(wù)器內(nèi)部轉(zhuǎn)發(fā)到該路徑,之后還是會(huì)經(jīng)過(guò)security的各個(gè)filter進(jìn)行登陸操作,最終登陸成功。這不是我要的,,所以需要自定義一個(gè)accessDeniedHandler。代碼如下,如果不是登陸請(qǐng)求的 csrf不匹配,都退出當(dāng)前用戶(hù),登陸用戶(hù)不做csrf校驗(yàn)。
@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(); //登陸頁(yè)面不做csrf校驗(yàn) http.csrf().ignoringAntMatchers("/login"); //異常處理 http.exceptionHandling(). accessDeniedHandler(csrfAccessDeniedHandler) }
看完上述內(nèi)容,你們對(duì)springboot中怎么利用security自定義CSRF防御有進(jìn)一步的了解嗎?如果還想了解更多知識(shí)或者相關(guān)內(nèi)容,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝大家的支持。
當(dāng)前文章:springboot中怎么利用security自定義CSRF防御
路徑分享:http://www.rwnh.cn/article32/gcgepc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供用戶(hù)體驗(yàn)、網(wǎng)站建設(shè)、面包屑導(dǎo)航、品牌網(wǎng)站設(shè)計(jì)、、企業(yè)網(wǎng)站制作
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)