国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 網站 > 幫助中心 > 正文

spring security中的csrf防御原理(跨域請求偽造)

2024-07-09 22:42:33
字體:
來源:轉載
供稿:網友

什么是csrf?

csrf又稱跨域請求偽造,攻擊方通過偽造用戶請求訪問受信任站點。CSRF這種攻擊方式在2000年已經被國外的安全人員提出,但在國內,直到06年才開始被關注,08年,國內外的多個大型社區和交互網站分別爆出CSRF漏洞,如:NYTimes.com(紐約時報)、Metafilter(一個大型的BLOG網站),YouTube和百度HI......而現在,互聯網上的許多站點仍對此毫無防備,以至于安全業界稱CSRF為“沉睡的巨人”。

舉個例子,用戶通過表單發送請求到銀行網站,銀行網站獲取請求參數后對用戶賬戶做出更改。在用戶沒有退出銀行網站情況下,訪問了攻擊網站,攻擊網站中有一段跨域訪問的代碼,可能自動觸發也可能點擊提交按鈕,訪問的url正是銀行網站接受表單的url。因為都來自于用戶的瀏覽器端,銀行將請求看作是用戶發起的,所以對請求進行了處理,造成的結果就是用戶的銀行賬戶被攻擊網站修改。

解決方法基本上都是增加攻擊網站無法獲取到的一些表單信息,比如增加圖片驗證碼,可以杜絕csrf攻擊,但是除了登陸注冊之外,其他的地方都不適合放驗證碼,因為降低了網站易用性

相關介紹:

http://baike.baidu.com/view/1609487.htm?fr=aladdin

spring-servlet中配置csrf

 <!-- Spring csrf 攔截器 --> <mvc:interceptors>  <mvc:interceptor>   <mvc:mapping path="/login" />   <bean class="com.wangzhixuan.commons.csrf.CsrfInterceptor" />  </mvc:interceptor> </mvc:interceptors>

在類中聲明Csrf攔截器,用來生成或去除CsrfToken

import java.io.IOException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.logging.log4j.LogManager;import org.apache.logging.log4j.Logger;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.method.HandlerMethod;import org.springframework.web.servlet.ModelAndView;import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;import com.wangzhixuan.commons.scan.ExceptionResolver;import com.wangzhixuan.commons.utils.WebUtils;/** * Csrf攔截器,用來生成或去除CsrfToken *  * @author L.cm */public class CsrfInterceptor extends HandlerInterceptorAdapter { private static final Logger logger = LogManager.getLogger(ExceptionResolver.class);  @Autowired  private CsrfTokenRepository csrfTokenRepository;  @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {  HandlerMethod handlerMethod = (HandlerMethod) handler;  // 非控制器請求直接跳出  if (!(handler instanceof HandlerMethod)) {   return true;  }  CsrfToken csrfToken = handlerMethod.getMethodAnnotation(CsrfToken.class);  // 判斷是否含有@CsrfToken注解  if (null == csrfToken) {   return true;  }  // create、remove同時為true時異常  if (csrfToken.create() && csrfToken.remove()) {   logger.error("CsrfToken attr create and remove can Not at the same time to true!");   return renderError(request, response, Boolean.FALSE, "CsrfToken attr create and remove can Not at the same time to true!");  }  // 創建  if (csrfToken.create()) {   CsrfTokenBean token = csrfTokenRepository.generateToken(request);   csrfTokenRepository.saveToken(token, request, response);   // 緩存一個表單頁面地址的url   csrfTokenRepository.cacheUrl(request, response);   request.setAttribute(token.getParameterName(), token);   return true;  }  // 判斷是否ajax請求  boolean isAjax = WebUtils.isAjax(handlerMethod);  // 校驗,并且清除  CsrfTokenBean tokenBean = csrfTokenRepository.loadToken(request);  if (tokenBean == null) {   return renderError(request, response, isAjax, "CsrfToken is null!");  }  String actualToken = request.getHeader(tokenBean.getHeaderName());  if (actualToken == null) {   actualToken = request.getParameter(tokenBean.getParameterName());  }  if (!tokenBean.getToken().equals(actualToken)) {   return renderError(request, response, isAjax, "CsrfToken not eq!");  }  return true; }  private boolean renderError(HttpServletRequest request, HttpServletResponse response,    boolean isAjax, String message) throws IOException {  // 獲取緩存的cacheUrl  String cachedUrl = csrfTokenRepository.getRemoveCacheUrl(request, response);  // ajax請求直接拋出異常,因為{@link ExceptionResolver}會去處理  if (isAjax) {   throw new RuntimeException(message);  }  // 非ajax CsrfToken校驗異常,先清理token  csrfTokenRepository.saveToken(null, request, response);  logger.info("Csrf[redirectUrl]:/t" + cachedUrl);  response.sendRedirect(cachedUrl);  return false; } /**  * 用于清理@CsrfToken保證只能請求成功一次  */ @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,   ModelAndView modelAndView) throws Exception {  HandlerMethod handlerMethod = (HandlerMethod) handler;  // 非控制器請求直接跳出  if (!(handler instanceof HandlerMethod)) {   return;  }  CsrfToken csrfToken = handlerMethod.getMethodAnnotation(CsrfToken.class);  if (csrfToken == null || !csrfToken.remove()) {   return;  }  csrfTokenRepository.getRemoveCacheUrl(request, response);  csrfTokenRepository.saveToken(null, request, response); }}
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 井研县| 齐齐哈尔市| 永胜县| 井冈山市| 保山市| 古交市| 清流县| 喜德县| 浦城县| 福清市| 尼玛县| 迁西县| 朝阳县| 武陟县| 湄潭县| 金秀| 南阳市| 比如县| 镇平县| 通州区| 蓬溪县| 上饶市| 清水河县| 丰宁| 乾安县| 马龙县| 嘉义市| 大石桥市| 绍兴县| 中江县| 绥芬河市| 育儿| 中超| 沙洋县| 夏津县| 双鸭山市| 彭州市| 高邑县| 讷河市| 葫芦岛市| 当阳市|