首页 文章

通过Angular调用时,Windows身份验证不能与WebAPI一起使用

提问于
浏览
0

我有两个项目,一个是MVC(使用Angular),另一个是WebAPI . Windows身份验证在MVC中运行正常(感谢article

但是,当我从MVC站点通过Angular向WebAPI进行AJAX调用时,我得到以下错误:

HTTP错误401.2 - 未经授权由于身份验证标头无效,您无权查看此页面 . 最有可能的原因:在IIS中未选择任何身份验证协议(包括匿名) . 仅启用了集成身份验证,并且使用了不支持集成身份验证的客户端浏览器 . 启用集成身份验证,并通过代理发送请求,该代理在到达Web服务器之前更改了身份验证标头 . Web服务器未配置为匿名访问,并且未收到所需的授权标头 . “configuration / system.webServer / authorization”配置部分可以明确地拒绝用户访问 .

我读了这个post但是它正在讨论HttpClient(当我使用JQuery或Angular时)来进行调用 .

PLEASE NOTE: 如果我通过浏览器点击WebAPI URL,那么身份验证工作正常 . 所以它必须与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)
    }
}

我做了足够的研究,但找不到解决方案 . 所以有几件事情 .

  • 如何解决上述问题

  • 其次,基于我的场景(和项目设置)使用Windows身份验证的最佳方法是什么 .

1 回答

  • 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());
    

相关问题