Our OData Endpoint is Standalone (OWIN). For one request: creating, updating, fixing and deleting everything works fine, but the problem is that I am sending a batch request with several actions in it, I have a problem with basic authorization. I read many articles, but still can not solve the problem. The OData documentation says:
Each body of the MIME part that represents one request MUST NOT include:
• 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
So, if I install authorization for a batch request, but do not install for each individual request in batch mode, I get null in actionContext.Request.Headers.Authorization in the OnAuthorization method. My question is: how can I get the packet request authorization header from the request in this batch?
At the endpoint, the Package is included:
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);
Here is the authorization logic:
public class ODataBasicAuthorizeAttribute : AuthorizeAttribute
{
public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
{
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);
}
}
}
}
Here is the test:
[TestMethod]
public void BatchRequestTest()
{
var odataAddress = "https://localhost:23170/Sample/Sample/OData/";
var batchUrl = $"{odataAddress}$batch";
HttpClient http = new HttpClient();
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");
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");
batchContent.Add(getRequestContent_1);
var getPassport = new HttpRequestMessage(HttpMethod.Get, $"{odataAddress}SAPassport");
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");
batchContent.Add(getRequestContent_2);
batchRequest.Content = batchContent;
HttpResponseMessage response = http.SendAsync(batchRequest).Result;
var responseString = response.Content.ReadAsStringAsync().Result;
}
If I set authorization for each individual request in a batch request, than it will work, but this seems to be wrong, so only the authorization header for Batch should be used.
Any ideas?
Thanks in advance,