如何向breeze批处理请求添加请求标头

时间:2014-05-29 17:28:13

标签: odata breeze asp.net-web-api2

请注意,这与向父请求添加标题不同,如另一个步骤所述:Breeze - Adding headers to request

我正在使用Breeze webApiOData dataservice&需要在批处理中的每个请求中添加特定的标头值。我可以将标头值添加到父请求中(使用前面提到的链接),但这不包含在子请求中。在我的具体实例中,我需要在请求中包含防伪令牌。批量请求被WebApi Odata控制器拆分为单独的请求,因此,他们看不到父请求。我正在探索如何调整服务器端代码以验证防伪标记,但是(1)只解决了我的特定挑战,(2)没有帮助其他可能需要包含请求中的标头值。  我正在使用breeze v1.4.12 ...查看来源,看来标题是明确设置的(第15280-15284行和第15380行)...所以我不清楚甚至可以在当前时间覆盖和控制批次中各个请求的内部标题。

具体来说,我在这样的请求中控制了防伪标记的包含,如下所示:

breeze.config.initializeAdapterInstance('dataService', 'webApiOData', true);

var unsecuredClient = OData.defaultHttpClient;
var securedClient = {
  request: function (request, success, error) {
    request.headers.RequestVerificationToken = jQuery("#__RequestVerificationToken").val();
    return unsecuredClient.request(request, success, error);
  }
};
OData.defaultHttpClient = securedClient;

当我查看发送到服务器的请求时,我在主要请求的标题中看到了令牌,但在内部请求中没有:

POST https://localhost:44362/odata/$batch HTTP/1.1
Host: localhost:44362
Connection: keep-alive
Content-Length: 585
Cache-Control: no-cache
Pragma: no-cache
RequestVerificationToken: fNR1OqB3SxNLF5EUI9mb-partial-rest-ommitted
MaxDataServiceVersion: 3.0
Origin: https://localhost:44362
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.114 Safari/537.36
Content-Type: multipart/mixed;boundary=batch_2a9d-ba3e-cf5f
Accept: multipart/mixed
DataServiceVersion: 2.0
Referer: https://localhost:44362/Home/SPA
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Cookie: ASP.NET_SessionId=jtfbzyt4zqk5pu43p1qop5tl; FedAuth=ommitted


--batch_2a9d-ba3e-cf5f
Content-Type: multipart/mixed; boundary=changeset_1fec-c63e-5864

--changeset_1fec-c63e-5864
Content-Type: application/http
Content-Transfer-Encoding: binary

POST odata/Projects HTTP/1.1
Content-ID: 1
DataServiceVersion: 2.0
Accept: application/atomsvc+xml;q=0.8, application/json;odata=fullmetadata;q=0.7, application/json;q=0.5, */*;q=0.1
Content-Type: application/json
MaxDataServiceVersion: 3.0

{"Id":-1,"Type":"SP.Data.Research_x0020_ProjectsListItem","eTag":null,"Title":"test"}
--changeset_1fec-c63e-5864--

--batch_2a9d-ba3e-cf5f--

当您查看原始响应时,您可以看到它无法在标题中找到令牌(在我单步执行服务器端代码时确认):

HTTP/1.1 202 Accepted
Cache-Control: no-cache
Pragma: no-cache
Content-Type: multipart/mixed; boundary=batchresponse_efc71196-045b-474c-bfe3-e21e20ae64b0
Expires: -1
Server: Microsoft-IIS/8.0
DataServiceVersion: 3.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?RDpcRGV2XFJlcG9zaXRvcmllc1xtc2Z0c3BjYW1yaVxzcmNcU3BSZXNlYXJjaFRyYWNrZXJcb2RhdGFcJGJhdGNo?=
X-Powered-By: ASP.NET
Date: Thu, 29 May 2014 16:42:00 GMT
Content-Length: 4432

--batchresponse_efc71196-045b-474c-bfe3-e21e20ae64b0
Content-Type: multipart/mixed; boundary=changesetresponse_aa3c98d6-a059-454d-9477-00e0b9497278

--changesetresponse_aa3c98d6-a059-454d-9477-00e0b9497278
Content-Type: application/http
Content-Transfer-Encoding: binary

HTTP/1.1 500 Internal Server Error
Content-ID: 1
Content-Type: application/json; odata=fullmetadata; charset=utf-8
DataServiceVersion: 3.0

{
  "odata.error":{
    "code":"","message":{
      "lang":"en-US","value":"An error has occurred."
    },"innererror":{
      "message":"The required anti-forgery cookie \"__RequestVerificationToken\" is not present.","type":"System.Web.Mvc.HttpAntiForgeryException","stacktrace":"   at System.Web.Helpers.AntiXsrf.TokenValidator.ValidateTokens(HttpContextBase httpContext, IIdentity identity, AntiForgeryToken sessionToken, AntiForgeryToken fieldToken)\r\n   at System.Web.Helpers.AntiXsrf.AntiForgeryWorker.Validate(HttpContextBase httpContext, String cookieToken, String formToken)\r\n   at System.Web.Helpers.AntiForgery.Validate()... bla bla bla"
    }
  }
}
--changesetresponse_aa3c98d6-a059-454d-9477-00e0b9497278--
--batchresponse_efc71196-045b-474c-bfe3-e21e20ae64b0--

@UPDATE - 对于权宜之计,我们实施了一个流程,当最初收到服务器端(使用自定义ODataBatchHandler,覆盖ValidateRequest()方法)时,我们抓住令牌从父请求中将其存储在缓存中。然后,当我们在控制器中验证请求时,我们首先检查属性是否在请求中(实际上是批处理的内部请求,因为一旦控制器获得请求,批处理被分成多个请求)如果没有,我们就会看到它是否在缓存中,有效地查看父请求。从缓存中删除值非常重要,就像我们在自定义ODataBatchHandler中的ProcessBatchAsync()一样,否则你会引入一个安全漏洞来保留多个请求。

1 个答案:

答案 0 :(得分:2)

好抓!

问题在于createChangeRequests方法(第15380行),该方法不支持内部请求的任何自定义调整。

我们将在内部进行讨论,以找到正式解决此问题的方法。短期内,除了创建OData数据服务适配器的自定义副本以及对此fnc的更改之外,我无法想到解决方法。呸。

你的时间表是什么时候?