首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >未找到Spring安全4卷csrf令牌

未找到Spring安全4卷csrf令牌
EN

Stack Overflow用户
提问于 2016-01-29 18:33:39
回答 2查看 2.2K关注 0票数 1

我知道这个问题以前被问了很多次,而且它应用了很多不同的方法,基于我在互联网上已经问过的问题,在这里,我有比我有答案的更多的问题。

所以,我有一个SpringMVC4.0 RESTful web服务,我知道它很好。我知道它工作正常,因为它通过了我的单元测试。具有附加安全性的单元测试和作为测试安全性的一部分的"csrf()“使其工作。我确实注意到这段数据:

代码语言:javascript
复制
Parameters = {_csrf=[435f9968-f643-47e9-9d15-23a5cb361b1d]}

RESTful web服务使用Security 4进行安全保护,默认情况下启用csrf保护。所有的网络服务得到了伟大的工作,是这篇文章是阻碍我与403错误。

以下是我试图实现的卷曲:

代码语言:javascript
复制
curl \
-d '{"SiteId\:"548","SubjectId":TEST_sub","description":"TEST_des"}' \
--cookie "csrftoken=?????????????" \
--cookie "JSESSIONID=openam~A7FF59011F982FBB91C2F908E143327D" \
--cookie  "iPlanetDirectoryPro=AQIC5wM2LY4Sfcy_7ZIwOhUsE4KK922nQEue1Bgm7wAtX_k.*AAJTSQACMDE.*; path=/; domain=.mydomain.net" \
-H "X-CSFRToken: ??????" -H "Accept: */*" -H "Content-Type: */*" \
-H "openam-token: AQIC5wM2LY4Sfcy_7ZIwOhUsE4KK922nQEue1Bgm7wAtX_k.*AAJTSQACMDE.*" \
https://spring.mydomain.net/api/subject/build

因此,我知道-d参数显式地做了一篇文章;我知道iPlanetDirectoryPro的-cookie是我的应用程序所需要的,我知道-H用于接受、内容类型和openam_token都是必需的。

我困惑的是: csfr令牌的-cookie .我从哪里得到这些数据的?会话id或JSESSIONID的-cookie?当我第一次登录我的网站时,我有一个曲奇:

代码语言:javascript
复制
JSESSIONID=openam~A7FF59011F982FBB91C2F908E143327D; path=/sso/; domain=spring-auth.mydomain.net; Secure; HttpOnly

现在,当谈到标题:它是X令牌还是.我都见过了。

我有一个SimpleCORSFilter,但是这个标题不是允许的,需要吗?我可以将它添加到可接受的标题列表中。

我担心将_csfr放入JSON数据中。如果我添加了Jackson,恐怕web服务将无法工作,因为_csrf没有一个匹配的对象,所以如果我添加了它,我就假设不使用它。

所以,我做了很多的尝试和错误的卷曲,我今天没有太多的运气。当我让卷发开始工作时,我必须把它传递给在UI上工作的承包商。他们正在使用JavaScript来创建对后端的AJX调用,这样他们就可以在URL中传递他们需要的任何东西,回发数据,并且他们可以添加他们需要的任何标题或cookie来传回数据。我把这个留给他们去弄清楚。

任何帮助我的卷发工作将是很好的。谢谢!

更新:当用户登录到我的应用程序时,我们使用SiteMinder示例的派生程序。也就是说,当我们成功地进行身份验证时,我们从OpenAM获得了一个cookie。然后,我们使用siteminder示例调用一个CustomUserDetailsService,它使用该cookie调用OpenAM并获取用户名。然后,我们对该用户名进行数据库查找,以获得该用户的角色。在所有这些中,我们是否返回任何类型的csrf令牌。因此,对于我在StackOverflow上看到的所有示例来说,没有csrf令牌可供我传回。在此之后,我添加了以下RESTful web服务。

代码语言:javascript
复制
@RequestMapping(value = "/csrf-token", method = RequestMethod.GET)
public @ResponseBody String getCsrfToken(HttpServletRequest request)
{
    CsrfToken token = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
    return token.getToken();
}

我可以在任何时候成功地调用这个URL,并获得一个令牌返回到客户端。例如:"45757c25-1af7-40d3-ab8b-1a9cd823efc5“

因此,我在两个地方测试这一点: RESTClient for Firefox和curl .

在RESTClient中,我可以发出请求并获得csrf令牌,然后我尝试将其放入RESTClient中,如下所示:

代码语言:javascript
复制
URL: https://spring.mydomain.net/api/subject/build?_csrf=[45757c25-1af7-40d3-ab8b-1a9cd823efc5]
Headers:  
openam_token: AQIC5wM2LY4SfczkVMBTIq4pyjcec7QkyN0PJbY3NdmF8WE.*AAJTSQACMDE.*
X-CSRF-TOKEN: [45757c25-1af7-40d3-ab8b-1a9cd823efc5]

还有什么是我需要的,因为它还没有起作用。

卷曲:

代码语言:javascript
复制
curl \
-d '{"SiteId\:"548","SubjectId":TEST_sub","description":"TEST_des"}' \
--cookie "csrftoken=45757c25-1af7-40d3-ab8b-1a9cd823efc5" \
--cookie "JSESSIONID=openam~A7FF59011F982FBB91C2F908E143327D" \
--cookie  "iPlanetDirectoryPro=AQIC5wM2LY4Sfcy_7ZIwOhUsE4KK922nQEue1Bgm7wAtX_k.*AAJTSQACMDE.*; path=/; domain=.mydomain.net" \
-H "X-CSFR-TOKEN: 45757c25-1af7-40d3-ab8b-1a9cd823efc5" 
-H "Accept: */*" -H "Content-Type: */*" \
-H "openam-token: AQIC5wM2LY4Sfcy_7ZIwOhUsE4KK922nQEue1Bgm7wAtX_k.*AAJTSQACMDE.*" \
https://spring.mydomain.net/api/subject/build

再说一次,我错过了什么让这件事成功?

我是否必须将我在RESTClient中的调用结合起来才能得到这个令牌,然后再发送到我的帖子呢?我该如何把这些卷曲组合起来?我知道每个会话都有一个csrf令牌,我想知道我可以打一个电话并得到这个令牌,然后在下一个请求中使用它来传递一个帖子。

我不做前端,我们有另一家公司正在处理UI和Ajax调用,我希望能够在将其传递给他们之前测试我的web服务调用。

再次感谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-02-02 20:06:49

经过大量的尝试和错误的努力,我终于找到了如何使这一工作。

我有一个正确的想法,基于以前的帖子,让我自己的控制器返回一个令牌,这一点在上面突出显示。当我打电话到该服务以获得令牌时,我还确保为JSESSION抓取了cookie。这是请求请求的会话,所以当我拿回令牌时,我必须确保我抓取了它:

代码语言:javascript
复制
Cookie:  JSESSIONID=3A74721AD18E758D7B8DC54FB32A6515; Path=/services/; HttpOnly
csrf_token: db7e3100-bd2d-4ecf-8c0d-20b8b4e17b20

现在,无论是使用火狐RESTClient还是使用curl,您都需要两样东西:

代码语言:javascript
复制
curl \
-d '{"SiteId\:"548","SubjectId":TEST_sub","description":"TEST_des"}' \
--cookie '\JSESSIONID=3A74721AD18E758D7B8DC54FB32A6515;' \
--cookie  "iPlanetDirectoryPro=AQIC5wM2LY4Sfcy_7ZIwOhUsE4KK922nQEue1Bgm7wAtX_k.*AAJTSQACMDE.*; path=/; domain=.mydomain.net" \
-H "X-CSFR-TOKEN: db7e3100-bd2d-4ecf-8c0d-20b8b4e17b20" 
-H "Accept: */*" -H "Content-Type: application/json" \
-H "openam-token: AQIC5wM2LY4Sfcy_7ZIwOhUsE4KK922nQEue1Bgm7wAtX_k.*AAJTSQACMDE.*" \
https://spring.mydomain.net/api/subject/build

注意,JSESSION id的cookie来自于我首先获得csrf令牌(db7e3100-bd2d-4ecf-8c0d-20b8b4e17b20)的请求。注意,我确实需要header令牌来包含令牌,并且我在SimpleCORSFilter中启用了该标头。

所以,这起作用了!我能够正确地将令牌传递给URL,并且我可以看到int日志。我可以看到对控制器的访问,以及我传入的数据。

REST控制器定义为:

代码语言:javascript
复制
@RequestMapping(value = "/build", method = RequestMethod.POST, produces = "application/json", headers = "Content-Type=application/json")
public MyEntity build(@RequestBody SubjectImportDTO subjectImportDTO)
{
    Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    User user = null;
    if (principal instanceof User)
    {
        user = ((User) principal);
    }
    MyEntity entity = service.build(subjectImportDTO);
    return entity;
}

现在,URL被找到,被调用,在后端执行工作,并且准备返回一个实体.但是我从curl或火狐RESTClient中得到一个404错误。我以为如果我们一开始找不到REST端点,就会创建404错误,所以这是我遇到的另一个问题。

票数 1
EN

Stack Overflow用户

发布于 2016-01-29 18:51:15

我不认为这完全回答了您的问题,但是下面是我添加csrf令牌所做的工作:

代码语言:javascript
复制
$(function () {
    var token = $("meta[name='_csrf']").attr("content");
    var header = $("meta[name='_csrf_header']").attr("content");
    $(document).ajaxSend(function(e, xhr, options) {
        xhr.setRequestHeader(header, token);
    });
});

我查看了我的一个请求头及其“X令牌”。

至于curl,我找到了其他测试方法,通常是在单独的测试配置中禁用CSRF。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35091592

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档