我有两个项目,一个是MVC(使用Angular),另一个是WebAPI。 Windows身份验证在MVC中运行正常(感谢此article)
然而,当我从MVC网站通过Angular向WebAPI进行AJAX调用时,我得到以下错误:
HTTP错误401.2 - 未经授权您无权查看此内容 页面由于身份验证标头无效。
最有可能的原因:
- 在IIS中未选择身份验证协议(包括匿名)。
- 仅启用了集成身份验证,并且使用了不支持集成身份验证的客户端浏览器。
- 启用了集成身份验证,并且请求是通过代理发送的,该代理更改了身份验证标头 到达Web服务器。
- 未配置Web服务器进行匿名访问,并且未收到所需的授权标头。
- “configuration / system.webServer / authorization”配置部分可能明确拒绝用户访问。
我读了这个post,但它正在谈论HttpClient(当我使用JQuery或Angular时)进行调用。
请注意:如果我通过浏览器点击了WebAPI网址,那么身份验证工作正常。所以它必须与AJAX请求有关。
这是我在Global.asax
中的代码protected void Application_BeginRequest()
{
if (ValidateRequest())
{
//var origin = Request.Headers["Origin"];
Response.Headers.Remove("Access-Control-Allow-Origin");
Response.AddHeader("Access-Control-Allow-Origin", matchedOrigin);
Response.Headers.Remove("Access-Control-Allow-Headers");
Response.AddHeader("Access-Control-Allow-Headers", CustomConfig.HEADERS);
Response.Headers.Remove("Access-Control-Allow-Methods");
Response.AddHeader("Access-Control-Allow-Methods", CustomConfig.METHODS);
}
// This is to avoid "Method 405 Not allowed" error
if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
{
Response.Flush();
Response.End(); //Send the Empty Response for Options (Preflight Request)
}
}
我做了足够多的研究,却找不到解决方案。所以有几件事。
答案 0 :(得分:0)
如果它直接在浏览器中工作,但在涉及JavaScript时则不然,这将是一个CORS问题,所以请检查是否已启用它,包括处理飞行前的OPTIONS动词。
在您的情况下,您还需要检查您是否通过了凭据,例如
[EnableCors(origins: "http://myclient.azurewebsites.net", headers: "*",
methods: "*", SupportsCredentials = true)]
注意凭据我不认为你可以拥有通配符 - 需要明确的列表。
请参阅此链接:https://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api#credentials。
在您的Angular $http
请求中,请确保您拥有属性withCredentials: true
。
或者如果您正在进行JQuery ajax调用,那么:
xhrFields: {
withCredentials: true
}
如果您仍有飞行前问题,请尝试这样的自定义消息处理程序(更改原点):
public class ExampleMessageHandler : DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
CancellationToken cancellationToken)
{
if (request.Headers.Contains("Origin") && request.Method.Method == "OPTIONS")
{
var response = new HttpResponseMessage();
response.StatusCode = HttpStatusCode.OK;
response.Headers.Add("Access-Control-Allow-Origin", "http://localhost:8080/");
response.Headers.Add("Access-Control-Allow-Credentials", "true");
response.Headers.Add("Access-Control-Allow-Headers", "Origin, Content-Type, Accept, Authorization");
response.Headers.Add("Access-Control-Allow-Methods", "DELETE, POST, PUT, OPTIONS, GET");
}
return base.SendAsync(request, cancellationToken);
}
}
然后:
public static void Register(HttpConfiguration config)
{
config.MessageHandlers.Add(new ExampleMessageHandler());