Odata 如何将请求头添加到批处理请求

Odata 如何将请求头添加到批处理请求,odata,breeze,asp.net-web-api2,Odata,Breeze,Asp.net Web Api2,请注意,这与在另一个步骤中向父请求添加头不同: 我使用的是breezewebapiodata数据服务&需要在批处理中的每个请求中添加一个特定的头值。我可以将头值添加到父请求中(使用上述链接),但子请求中不包括头值。在我的特定实例中,我需要在请求中包含一个反伪造令牌。批处理请求由WebApi Odata控制器拆分为单个请求,因此,它们看不到父请求。我正在探索如何调整中验证防伪令牌的服务器端代码,但这(1)只解决了我的特定问题,(2)对可能需要在请求中包含头值的其他人没有帮助。  我正在使用bre

请注意,这与在另一个步骤中向父请求添加头不同:

我使用的是breezewebapiodata数据服务&需要在批处理中的每个请求中添加一个特定的头值。我可以将头值添加到父请求中(使用上述链接),但子请求中不包括头值。在我的特定实例中,我需要在请求中包含一个反伪造令牌。批处理请求由WebApi Odata控制器拆分为单个请求,因此,它们看不到父请求。我正在探索如何调整中验证防伪令牌的服务器端代码,但这(1)只解决了我的特定问题,(2)对可能需要在请求中包含头值的其他人没有帮助。  我正在使用breeze v1.4.12。。。查看源代码,似乎正在显式设置标题(第15280-15284行和第15380行)。。。因此,目前我还不清楚是否可以覆盖和控制批处理中单个请求的内部头

具体地说,我正在控制请求中包含的antiforgery令牌,如breeze所示:

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--
当您查看原始响应时,您可以看到它如何在头中找不到令牌(当我逐步查看服务器端的代码时确认):

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

很好

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

我们将进行内部讨论,以找到正式解决这一问题的方法。短期内,除了创建ODataDataService适配器的自定义副本并更改此fnc之外,我想不出其他解决方法。恶心


你的时间表是什么?

啊。。。很高兴知道我的看法是正确的:)很高兴听到这个问题会得到解决!我已经将我们当前的解决方案添加到我的初始帖子中,作为权宜之计。从v.1.4.14开始,您可以使用。
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--