【问题标题】:Azure AD API request 401 UnauthorizedAzure AD API 请求 401 未经授权
【发布时间】:2016-07-08 08:23:00
【问题描述】:

我在启用了 Azure AD 身份验证的 Azure 网站上运行了一个标准 Web API,当在浏览器中浏览 API 时,我可以通过浏览器登录并访问 API。

但是,WPF 桌面应用程序在提交请求时收到未经授权的响应:

var authContext = new AuthenticationContext(authority, new FileCache());
var accessToken = await authContext.AcquireTokenAsync(apiResourceid, clientId, redirectUri,
                    new PlatformParameters(PromptBehavior.Auto));
// accessToken is valid

var apiUrl = "https://example.azurewebsites.net/api/list";
var request = new HttpRequestMessage(HttpMethod.Get, apiUrl);
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken.AccessToken);
var response = await httpClient.SendAsync(request);

认证成功,调试时可以看到用户信息。

我无权访问 Azure 帐户,但我确信 Service AD 应用程序配置正确,允许访问客户端 AD 应用程序,因为在备用帐户(未正确配置)上进行测试时,AuthenticationContext.AcquireTokenAsync 方法失败了。

我确实注意到 AuthenticationResult.ExpiresOn 总是在过去,但看不到延长它的方法,这应该是未来的日期吗? -(时间当然是 UTC)

请求:

GET https://example.azure
websites.net/api/categorisation HTTP/1.1
Authorization: Bearer eyJ0eXAiO...
Host: example.azurewebsites.net

回复:

HTTP/1.1 401 Unauthorized
Content-Length: 58
Content-Type: text/html
Server: Microsoft-IIS/8.0
WWW-Authenticate: Bearer realm="example.azurewebsites.net"
X-Powered-By: ASP.NET
Set-Cookie: ARRAffinity=e35f2977dba55e6708887e762940f75c2a0fcb0a9df4e1cbe0d3f10a614c59b8;Path=/;Domain=example.azurewebsites.net
Date: Fri, 08 Jul 2016 07:51:13 GMT

You do not have permission to view this directory or page.

更新:

我已经在我有权访问的 Azure 帐户中重新创建了环境,但仍然收到未经授权的响应(在浏览器中可以正常工作)。

【问题讨论】:

  • 您能否在您的网站 Startup.Auth.cs 中发布代码以设置 Azure AD 身份验证?或者,如果您在 Azure 网站中使用“身份验证/授权”选项,您能否分享您配置的值/设置?
  • 另外,关于这个:“身份验证成功,调试时我可以看到用户信息。”,你是说用 Visual Studio 运行 WPF 应用程序时,你成功连接到 API,但是当从exe运行它不?如果是这样,您在运行 .exe 时是否会收到提示?
  • @Saca API 正在使用 Azure 网站身份验证。 Provider 是使用 Express Management Mode 配置的“Azure Active Directory”,Azure AD App 设置为 AD Web Service 应用程序。
  • @Saca 不幸的是,API 请求在调试或运行 exe 时总是收到 401。在这两种情况下,AcquireToken 都是成功的。
  • 使用 Pluralsight 中配置为使用我的 Azure AD 的代码示例在本地工作,但是当我部署到 Azure(并禁用自动身份验证)时,客户端应用程序无法访问 API。

标签: c# .net asp.net-web-api azure-active-directory


【解决方案1】:

问题似乎与 Azure 网站中的“身份验证/授权”选项有关,启用后,Web Api 将不接受使用身份验证标头的请求。禁用该选项并将 Owin 库与 Azure AD 一起使用提供了所需的解决方案。

【讨论】:

  • 对我来说同样如此,我创建了另一个没有 web api 的项目,并且 azure auth 开箱即用
【解决方案2】:

我知道这已经有几个月了,但是当我得到它时,我想扔掉导致这个问题的原因,以及我发现我可以做些什么来解决它。

我有一个使用 SignalR 制作的网站。在开发过程中,我没有保护站点,但是当我使用 AzureAD 保护站点时,出现了上述错误。问题是我有两个启动类,一个在应用程序根目录中,一个在 App_Start 中。一个在 [applicationname].App_Start 命名空间中,一个在 App_Start 命名空间中,一个被标记为 OWIN 启动程序集。

我的解决方案是删除 App_Start 文件夹中的那个,它位于 [appname].App_Start 命名空间中,并将正确的 SignalR 和 OWIN 启动属性添加到应用程序根目录中的那个。

这解决了我的问题。

希望这对遇到此问题的其他人有所帮助!

【讨论】:

    【解决方案3】:

    我也遇到了未经授权的错误,在获得不记名令牌时,一切似乎都正常。

    我的问题在于我的资源 ID。它与我的 Azure-AD 应用程序的“App ID URI”不匹配。在调用 AcquireTokenAsync 方法时,我在末尾有一个额外的斜线,并且我在 Azure-AD 中输入了它而没有斜线。

    // private string resourceId = "https://mywebsite.azurewebsites.net/"; // bad
    private string resourceId = "https://mywebsite.azurewebsites.net"; // good
    result = await authContext.AcquireTokenAsync(resourceId, 
       clientId, redirectUri, new PlatformParameters(PromptBehavior.Never));
    

    因此,请确保您的资源 ID 与您的 Azure-AD 应用程序的“App ID URI”完全匹配。

    注意事项:

    • 与 Azure-AD 关联的每个应用程序服务都有一个相应的 Web 应用程序/API 类型的 Azure-AD 应用程序声明。此资源 ID 是应用服务的 Azure-AD 应用程序声明中的“应用 ID URI”。
    • 我的资源 ID 恰好是我的网站 URL,但它可能是任何东西。关键是要匹配您尝试访问的 Azure-AD 应用程序的“APP ID URI”。

    【讨论】:

      【解决方案4】:

      只有我的 5 美分。有点晚了,但如果这对某人有帮助,那就太棒了。

      对我来说,问题是:没有随请求一起正确发送范围。

      背景: localhost 节点服务器,使用官方的 graph-api quickstart repo。 REST API-server - 在 azure 上运行的应用服务,带有 Auth。 (快速模式)已启用。

      我犯了一个严重错误,而且花了很长时间才弄明白。我试图用错误的访问令牌调用 API。

      可以仅使用“openid”、“profile”等范围调用 GRAPH API。

      但要访问 Web API,我必须使范围包括 API url Scopes = "https://yourwebsiteurl.com/allowed_scope" 而不仅仅是 "allowed_scope"。即使使用范围作为“应用程序 ID URI”/allowed_scope 的应用程序 ID URI 也不起作用,除非“应用程序 ID URI”是 API url。

      如果您尝试使用不存在的范围或类似的范围调用 API,Azure 会抛出一个明确的错误,但在这种情况下,如果您没有在范围内包含真正的 API url - 错误只是 401,什么都没有否则。

      Azure 中的“应用程序 ID URI”配置实际上似乎没有什么不同,似乎它几乎可以是任何东西。 - 而 API 调用范围必须包含整个 API url。

      【讨论】:

        【解决方案5】:

        花了几个小时试图找出问题所在,通常情况下,问题很简单。 Postman 提供 RestSharp C# 代码,如果您使用的是 HttpClient,这只是一个格式问题。使用:

        var httpClient = new HttpClient();
        httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer tokenValueLongStringHere);
        

        在我的情况下使用 httpClient.DefaultRequestHeaders.Authorization 不起作用。

        【讨论】:

          猜你喜欢
          • 2020-04-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-23
          • 2012-08-17
          • 2016-10-24
          • 1970-01-01
          相关资源
          最近更新 更多