Security+前后端分离CSRF使用

Posted £漫步 云端彡

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Security+前后端分离CSRF使用相关的知识,希望对你有一定的参考价值。

Security+前后端分离CSRF使用

Security默认是开启CSRF保护的,与此类似的是CORS。具体我不是很了解,只知道CORS是管理跨域资源共享使用,CSRF是保护网络攻击的。
开发环境中经常通过API post或者其他请求访问调试,这样子也就说明,可以通过http请求随意访问。因此开启CSRF保护,表示不可通过API post调试工具调试。
这样又出现了另外一个问题,前后端分离的情况下,怎么能通过CSRF调用呢?

Security是由多个过滤器组成,CSRF实现也不例外,它是由CsrfFilter这个过滤器类实现的,CsrfFilter是对保密性的请求拦截,对于(GET|HEAD|TRACE|OPTIONS)是不拦截的。tokenRepository对象是保管toekn值的
源码的处理如下图:

这里做了六步处理:

  1. 获取本地存储的csrfTken
  2. 验证是否第一个CSRF校验请求,是则创建一个csrfTken保存起来,不是下一步
  3. 在请求request中加入csrfTken属性值
  4. 如果是GET|HEAD|TRACE|OPTIONS请求,通过
  5. 获取request中携带的csrfToken值,名为actualToken
  6. 比对actualToken和csrfTken是否相同,相同通过,不同报错

因此解决办法的思路重点在request。

  1. 首先肯定得过滤一个不需要csrfToken的请求吧
// security配置文件,其余配置不介绍
   /**
     * 拦截请求后的权限设置
     *
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
              // 网络防护忽略请求
                .csrf().ignoringAntMatchers("/user/login")
    }
  1. 这个登录请求成功后,csrfToken会保存在request中
// 在登录成功处理器中保存这个token
/**
 * 获取CSRF密钥
 *   "csrf": {
 *       "headerName": "X-CSRF-TOKEN",  必须是这个作为key
 *       "parameterName": "_csrf", 这个key值目前不清楚为什么获取不到值
 *       "token": ""
 *   },
 *   向前端发送密钥,每次请求写在头信息中,
 *   例如 X-CSRF-TOKEN: 'token',即可保证正常访问
 */
CsrfToken csrfToken = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
  1. 然后将这个值传递到前端,前端保存,在每次请求头中添加这个值即可验证成功
    this.axios.post(`${API_HOST}/login`, obj, {
        headers: {
            'X-CSRF-TOKEN': token
        }
    }).then(function(response) {
        const data = response.data;
    }, function(response) {});

以上是关于Security+前后端分离CSRF使用的主要内容,如果未能解决你的问题,请参考以下文章

71. Django 前后端分离csrf token获取方式

前后端分离架构下 CSRF 防御机制

第712期前后端分离架构下CSRF防御机制

vue+flask前后端分离解决csrf token问题

前后端分离,解决跨域问题及django的csrf跨站请求保护

前后端分离下spring security 跨域问题等