通过Angular

时间:2016-10-31 18:42:38

标签: angularjs ajax asp.net-mvc authentication asp.net-web-api

我有两个项目,一个是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)
    }
}

我做了足够多的研究,却找不到解决方案。所以有几件事。

  • 如何解决上述问题
  • 其次,基于我的场景(和项目设置)使用Windows身份验证的最佳方法是什么。

1 个答案:

答案 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());