У меня есть веб-api, чтобы разрешить доступ к перекрестному домену с помощью Basic Authentication. Когда я делаю запрос GET для кросс-домена API, он отлично работает, и я получаю токен в заголовке «Авторизация» в своем обработчике сообщений. Но при запуске запроса POST для перекрестного домена я не получаю заголовок «Авторизация», поэтому не удается проверить запрос.Веб-Api Cross Domain Основная проверка подлинности
Любая помощь будет высоко оценена.
Ниже приведен код моего специального обработчика сообщений для доступа к перекрестному домену.
using System;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
namespace MyWebApi.Handlers
{
public class XHttpMethodOverrideDelegatingHandler : DelegatingHandler
{
static readonly string[] HttpOverrideMethods = { "PUT", "DELETE" };
static readonly string[] AccessControlAllowMethods = { "POST", "PUT", "DELETE" };
private const string HttpMethodOverrideHeader = "X-HTTP-Method-Override";
private const string OriginHeader = "ORIGIN";
private const string AccessControlAllowOriginHeader = "Access-Control-Allow-Origin";
private const string AccessControlAllowMethodsHeader = "Access-Control-Allow-Methods";
private const string AccessControlAllowHeadersHeader = "Access-Control-Allow-Headers";
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var authHeader = request.Headers.Authorization;
if (authHeader == null || authHeader.Scheme != "Basic" || string.IsNullOrWhiteSpace(authHeader.Parameter))
{
return CreateUnauthorizedResponse();
}
if (request.Method == HttpMethod.Post && request.Headers.Contains(HttpMethodOverrideHeader))
{
var httpMethod = request.Headers.GetValues(HttpMethodOverrideHeader).FirstOrDefault();
if (HttpOverrideMethods.Contains(httpMethod, StringComparer.InvariantCultureIgnoreCase))
request.Method = new HttpMethod(httpMethod);
}
var httpResponseMessage = base.SendAsync(request, cancellationToken);
if (request.Method == HttpMethod.Options && request.Headers.Contains(OriginHeader))
{
httpResponseMessage.Result.Headers.Add(AccessControlAllowOriginHeader, request.Headers.GetValues(OriginHeader).FirstOrDefault());
httpResponseMessage.Result.Headers.Add(AccessControlAllowMethodsHeader, String.Join(", ", AccessControlAllowMethods));
httpResponseMessage.Result.Headers.Add(AccessControlAllowHeadersHeader, HttpMethodOverrideHeader);
httpResponseMessage.Result.StatusCode = HttpStatusCode.OK;
}
//No mater what the HttpMethod (POST, PUT, DELETE), if a Origin Header exists, we need to take care of it
else if (request.Headers.Contains(OriginHeader))
{
httpResponseMessage.Result.Headers.Add(AccessControlAllowOriginHeader, request.Headers.GetValues(OriginHeader).FirstOrDefault());
}
return httpResponseMessage;
}
private Task<HttpResponseMessage> CreateUnauthorizedResponse()
{
var response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
response.Headers.Add("WWW-Authenticate", "Basic");
var taskCompletionSource = new TaskCompletionSource<HttpResponseMessage>();
taskCompletionSource.SetResult(response);
return taskCompletionSource.Task;
}
}
}
И я зарегистрировал выше обработчик в Application_Start следующим образом:
namespace MyWebApi
{
public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
RouteTable.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new {id = RouteParameter.Optional});
GlobalConfiguration.Configuration.MessageHandlers.Add(new XHttpMethodOverrideDelegatingHandler());
GlobalConfiguration.Configuration.Formatters.Insert(0, new JsonpMediaTypeFormatter());
}
}
}
На стороне клиента на другой проект домена, я пытаюсь добавить новую запись, используя следующий код.
AddUser {
var jsonData = {
"FirstName":"My First Name",
"LastName": "My Last Name",
"Email": "[email protected]",
"Password": "MyPa$$word"
};
$.ajax({
type: "POST",
dataType: 'json',
url: "http://localhost:4655/api/user/signup",
beforeSend: function (xhr) { xhr.setRequestHeader("Authorization", "Basic xxxxxxxxxxxxxx"); },
accept: "application/json",
data: JSON.stringify(jsonData),
success: function (data) {
alert("success");
},
failure: function (errorMsg) {
alert(errorMsg);
},
error: function (onErrorMsg) {
alert(onErrorMsg.statusText);
},
statusCode: function (test) {
alert("status");
}
});
});
И ниже приведен код для моего пользовательского контроллера.
namespace MyWebApi.Controllers
{
public class UserController : ApiController
{
[HttpPost]
[ActionName("Adduser")]
public int Post(UserModel source)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
Db.Users.Add(source);
Db.SaveChanges();
return source.UserId;
}
}
}
Заранее благодарен!
Я тоже пытаюсь подключить до службы Web API REST, чтобы базовое разрешение и обеспечить возможность CORS запросов (GET и POST). Основываясь на приведенной ниже статье, я задаюсь вопросом, считается ли это лучшей практикой использовать этот код в производстве. Вам удалось заставить это работать? http://blog.bittercoder.com/2012/09/09/cors-and-webapi/ – likestoski
К сожалению, нет. Я не нашел способ заставить его работать. И из-за сложностей и зависимостей браузера я отказался от этого, чтобы использовать CORS API WEB. – tahir76