springsecurity:使用从 CrossOrigin REST 服务获得的 CSRF 令牌来发布数据

Posted

技术标签:

【中文标题】springsecurity:使用从 CrossOrigin REST 服务获得的 CSRF 令牌来发布数据【英文标题】:springsecurity: using CSRF token obtained from CrossOrigin REST service to POST data 【发布时间】:2019-04-12 12:57:47 【问题描述】:

我在domainA 上有这个 REST 服务:

@CrossOrigin(origins="http://domainB")
@RequestMapping(value="/csrf", method=RequestMethod.GET)
public @ResponseBody
CsrfToken getCsrfToken(HttpServletRequest request) 
    CsrfToken token = (CsrfToken)request.getAttribute(CsrfToken.class.getName());
    return token;

然后我想从上述服务获取 CSRF 令牌(通过在 domainB 上使用 javascript)并将其添加到 domainB 上的 <form action="http://domainA> 并将此表单发送到 domainA(这是一个简单的表单,具有提交按钮)。

问题是我得到 HTTP 状态 403 - 禁止。

相反:当我在<form action="http://domainA> 中手动设置_csrf 值(在指向domainA/csrf 的其他浏览器选项卡中手动获得)并提交时,它就可以工作了。

我注意到的不同之处在于,当我手动刷新浏览器的选项卡 domainA/csrf 时,我会不断得到相同的值(并且该值有效),但是当 domainA/csrf 是由 javascript 从 domainB 获取时每次都不同,使用时 - 它不起作用。

谁能帮忙?


域A:www.fridayweekend.com/rest/csrf

domainB:www.friwee.com/register(按 F12 并观察对 www.fridayweekend.com/rest/csrf 的调用返回......)

【问题讨论】:

【参考方案1】:

正如@dur 所说 - 问题出在 JavaScript 代码中。我用过:

$.getJSON(domainA/csrf, callback)

每次都会以一个新会话和一个新的 CSRF 令牌结束。

解决方法是使用cors_ajax_call函数,除了$.getJSON,定义如下:

var cors_ajax_call = function(address, callback)

  $.ajax(
      url: address,
      context: document.body,
      xhrFields: 
          withCredentials: true
      
  ).success(callback);

感谢您的意见!希望这对某人有帮助:)

【讨论】:

以上是关于springsecurity:使用从 CrossOrigin REST 服务获得的 CSRF 令牌来发布数据的主要内容,如果未能解决你的问题,请参考以下文章

使用SpringSecurity体验OAuth2 (入门2)

SpringSecurity从入门到精通:从数据库查询权限信息&自定义失败处理

使用SpringSecurity验证token

Django实现跨域请求 񽋝

SpringSecurity能否吊打Shiro?

Grails/SpringSecurity:如何在不被识别的情况下创建用户?