gpt4 book ai didi

c# - OData V4 批量请求基础授权

转载 作者:行者123 更新时间:2023-12-02 11:21:32 24 4
gpt4 key购买 nike

我们的 OData 端点是自托管 (OWIN)。对于单个请求:创建、更新、修补和删除一切都很好,但问题是当我发送包含多个操作的批处理请求时,我遇到了基本授权问题。
我读了很多文章,但仍然无法解决问题。
在 OData 文档中,它说:

代表单个请求的每个 MIME 部分主体不得包括:

• authentication or authorization related HTTP headers

http://docs.oasis-open.org/odata/odata/v4.0/errata03/os/complete/part1-protocol/odata-v4.0-errata03-os-part1-protocol-complete.html#_Toc453752314

因此,如果我将 Authorization 设置为批量请求,但未批量设置为每个单个请求,则 OnAuthorization 方法中的 actionContext.Request.Headers.Authorization 将变为 null。
我的问题是:如何从该 Batch 中的请求中获取 Batch 请求的 Authorization header ?

在端点批处理中启用:
HttpConfiguration config = new HttpConfiguration();
var odataBatchHandler = new DefaultODataBatchHandler(new HttpServer(config));
config.MapODataServiceRoute("ODataApi", null, builder.GetEdmModel(), odataBatchHandler);
config.Count().Filter().OrderBy().Expand().MaxTop(null).Select();
appBuilder.UseWebApi(config);

下面是授权逻辑:
public class ODataBasicAuthorizeAttribute : AuthorizeAttribute
{
public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
{
//Question: here Authorization property is null, because this is Get request for SAStudent
if (actionContext.Request.Headers.Authorization == null || actionContext.Request.Headers.Authorization.Scheme != "Basic")
{
HandleUnauthorizedRequest(actionContext);
}
else
{
ISession session = Login(actionContext.Request);
if (session == null)
{
HandleUnauthorizedRequest(actionContext);
}
else
{
IsAuthorized(actionContext);
}
}
}
}

这是测试:
    [TestMethod]
public void BatchRequestTest()
{
var odataAddress = "https://localhost:23170/Sample/Sample/OData/";
var batchUrl = $"{odataAddress}$batch";
HttpClient http = new HttpClient();
// Global batch request
HttpRequestMessage batchRequest = new HttpRequestMessage(HttpMethod.Post, batchUrl);
batchRequest.Headers.Authorization = new AuthenticationHeaderValue("Basic", "QWRtaW5pc3RyYXRvcjpwdw==");
MultipartContent batchContent = new MultipartContent("mixed", "batch_" + Guid.NewGuid().ToString());

var getStudent = new HttpRequestMessage(HttpMethod.Get, $"{odataAddress}SAStudent");
//getStudent.Headers.Authorization = new AuthenticationHeaderValue("Basic", "QWRtaW5pc3RyYXRvcjpwdw==");
// First message content with GET request
HttpMessageContent getRequestContent_1 = new HttpMessageContent(getStudent);
getRequestContent_1.Headers.Remove("Content-Type");
getRequestContent_1.Headers.Add("Content-Type", "application/http");
getRequestContent_1.Headers.Add("Content-Transfer-Encoding", "binary");
// Add this GET content to the batch content
batchContent.Add(getRequestContent_1);

var getPassport = new HttpRequestMessage(HttpMethod.Get, $"{odataAddress}SAPassport");
//getPassport.Headers.Authorization = new AuthenticationHeaderValue("Basic", "QWRtaW5pc3RyYXRvcjpwdw==");
// Second message content with GET request
HttpMessageContent getRequestContent_2 = new HttpMessageContent(getPassport);
getRequestContent_2.Headers.Remove("Content-Type");
getRequestContent_2.Headers.Add("Content-Type", "application/http");
getRequestContent_2.Headers.Add("Content-Transfer-Encoding", "binary");
// Add this GET content to the batch content
batchContent.Add(getRequestContent_2);

// Here we go
batchRequest.Content = batchContent;
HttpResponseMessage response = http.SendAsync(batchRequest).Result;
var responseString = response.Content.ReadAsStringAsync().Result;

}

如果我为 Batch 请求中的每个单个请求设置 Authorization 比它会工作,但它似乎不正确,所以只将授权 header 设置为 Batch 应该可以工作。

有任何想法吗?

提前致谢,

最佳答案

迟到了,但最近遇到了类似的问题,尽管是使用 Http Cookie 进行自定义身份验证。
首先,确保 Web Api 和 Batch Handler 配置为使用相同的 HttpServer 实例。

HttpConfiguration config = new HttpConfiguration();
HttpServer httpServer = new HttpServer(config);
var odataBatchHandler = new DefaultODataBatchHandler(httpServer);
config.MapODataServiceRoute("ODataApi", null, builder.GetEdmModel(), odataBatchHandler);
config.Count().Filter().OrderBy().Expand().MaxTop(null).Select();
appBuilder.UseWebApi(httpServer);
我发现如果没有这个,来自封闭 $batch 请求的任何上下文都不会对每个子请求可用,因为 odata 批处理处理程序使用了不同的 HttpServer 实例到 web api。
我现在可以为我的自定义身份验证从 OwinContext 中获取标题 - 在你的情况下......
public class ODataBasicAuthorizeAttribute : AuthorizeAttribute
{
public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
{
//Question: here Authorization property is null, because this is Get request for SAStudent

var isBatch = request.Properties.TryGetValue("MS_BatchRequest", out var value) ? (bool)value : default;
OwinContext owinContext = request.Properties.TryGetValue("MS_OwinContext", out var owinCtxObj) ? (OwinContext)owinCtxObj : default;
if (isBatch && owinContext != null)
{
// adjust your auth logic to use the owin context... my case I needed a cookie, so...
// var jwtCookieKeyValuePair = owinContext.Request.Cookies.FirstOrDefault(cookie => cookie.Key == "jwt");
}
// Keep your existing logic for non-batch odata requests..
if (actionContext.Request.Headers.Authorization == null || actionContext.Request.Headers.Authorization.Scheme != "Basic")
{
HandleUnauthorizedRequest(actionContext);
}
else
{
ISession session = Login(actionContext.Request);
if (session == null)
{
HandleUnauthorizedRequest(actionContext);
}
else
{
IsAuthorized(actionContext);
}
}
}
}
对于 OP 而言,一切都可能为时已晚,但可能会对某人有所帮助。

关于c# - OData V4 批量请求基础授权,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48801143/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com