通过 Angular 调用时,Windows 身份验证不适用于 WebAPI

Posted

技术标签:

【中文标题】通过 Angular 调用时,Windows 身份验证不适用于 WebAPI【英文标题】:Windows Authentication is not working with WebAPI when called through Angular 【发布时间】:2017-03-13 21:49:54 【问题描述】:

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

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

HTTP 错误 401.2 - 未经授权 您无权查看此内容 由于身份验证标头无效而导致的页面。

最可能的原因:

在 IIS 中未选择身份验证协议(包括匿名)。 仅启用了集成身份验证,并且使用了不支持集成身份验证的客户端浏览器。 已启用集成身份验证,并且请求是通过代理发送的,该代理在验证标头之前更改了它们 到达网络服务器。 Web 服务器未配置为匿名访问,并且未收到所需的授权标头。 “configuration/system.webServer/authorization”配置部分可能明确拒绝用户访问。

我读到了这个post,但它是在谈论 HttpClient(当我使用 JQuery 或 Angular 时)进行调用。

请注意:如果我通过浏览器点击 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】:

如果它直接在浏览器中工作,但在涉及 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());

【讨论】:

我怀疑这是一个 CORS 问题,因为在我在 WebAPI 项目上启用 Windows 身份验证之前它运行良好。我相信它必须对凭据做一些事情,但不知道是什么。 谢谢本。您的建议有效但不完全。现在对于飞行前(选项)请求,我得到 401 未经授权,因为我的研究浏览器不发送选项请求的凭据。我猜 WebAPI 正在寻找凭据。我可以通过关注这篇文章 [link]***.com/a/28439989/1813357 来解决问题,但不确定这是否是一个好的解决方案。 消息处理程序为 GET 请求执行,但它不会被 OPTIONS 请求命中。我正在处理 Global.asax Application_BeginRequest 中的 OPTIONS 动词,就像在示例帖子中所做的那样。 让我们continue this discussion in chat.

以上是关于通过 Angular 调用时,Windows 身份验证不适用于 WebAPI的主要内容,如果未能解决你的问题,请参考以下文章

Angular 5 应用程序的任何组件访问数据。正在通过身份验证服务中的 API 调用设置数据

Angular 7 .net 核心 2.2 WebApi Windows 身份验证 CORS

为啥 Angular Oninit 仅在离开页面时才调用服务

如何将 Web api Windows 身份验证与 Angular 应用程序一起使用 [重复]

Windows 身份验证和 Angular 4 应用程序

使用 Windows 身份验证登录 Angular App