我们的OData端点是自托管(OWIN)。对于单个请求:创建,更新,修补和删除所有内容都很好,但是问题是当我发送包含多个操作的批处理请求时,基本授权出现了问题。我读了很多文章,但仍然无法解决问题。在OData文档中说:
表示单个请求的每个MIME部分正文都不得包括:
• authentication or authorization related HTTP headers
因此,如果我将Authorization设置为批处理请求,但未将其设置为批处理中的每个单个请求,则OnAuthorization方法中的actionContext.Request.Headers.Authorization会为null。我的问题是:如何从该批次中的请求中获取批次请求的授权标头?
启用了端点批处理:
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;
}
如果我将批处理请求中的每个请求都设置为授权,那么它将起作用,但是似乎不正确,因此仅将授权标头设置为批处理应该起作用。
有什么想法吗?
谢谢,
您找到解决方案了吗?