Azure AD 服务器身份验证,无权查看目录

Azure AD server authentication, No permission to view directory

我创建了一个 Xamarin.Forms 项目和一个 Table API 项目。两者都是通过 Azure 门户中的“快速启动”菜单创建的。

我已经在我的门户中配置了一个 Azure AD,我可以通过我的 XForms 应用程序成功地从 AD 检索令牌。但是当我尝试使用 MobileServiceClient 的 LoginAsync 方法登录到 Table API 时,我收到 "You do not have permission to view til directory or page."

我一直在浏览以下指南,但没有成功。

How to configure your App Service application to use Azure Active Directory login

Add authentication to your Xamarin.Forms app

How to: Work with authentication

我也看了下面的问题,但没有找到解决方案。

Cordova AAD server flow authentication hangs on Android and iOS

我在想我可能在 Table API 项目上缺少一些特定的身份验证?

这是我的代码和设置:

PCL XFORMS 中的项目

var ar = await authContext.AcquireTokenAsync(Constants.GraphResourceUri, Constants.ClientId, userCredintials);

            JObject payload = new JObject();
            payload["access_token"] = ar.AccessToken;

            var client = new MobileServiceClient(Constants.ApplicationUrl);
            var user = await client.LoginAsync(MobileServiceAuthenticationProvider.WindowsAzureActiveDirectory, payload);

Constants.ClientID 是 Native Client 应用程序的 ClientId,而不是网络服务器。如果我切换它,我会得到 404。

来自 TABLE API 项目的控制器示例

[Authorize]
public class StatisticController : ApiController

TABLE API StartUp.cs 配置

public void Configuration(IAppBuilder app)
    {
        app.UseAppServiceAuthentication(new AppServiceAuthenticationOptions());
        ConfigureMobileApp(app);
    }

移动服务授权设置

单一 SING-ON 广告设置

本地客户端应用程序设置

编辑

我可以使用以下设置通过 PostMan 复制错误:

我尝试将 "X-ZUMO-AUTH" header 包含在 access_token 的值中,但结果相同。仍然没有许可。我还尝试排除 POST 请求中的每个 header 但没有任何更改。 这是否意味着不允许来自我的移动应用或 Postman 的 POST 请求?

如果我在浏览器中手动浏览到 mysite.azurewebsites.net/.auth/login/aad,那么我可以使用我的 AD 中的用户登录。因此,AD 似乎与服务正确通信,反之亦然。

已修复

非常感谢mattchenderson!正如他建议的那样,我应该将常量 GraphResourceUri 更改为我的服务的客户端 ID,而不是普通图 api。随着添加单个客户端实例,我现在可以成功登录到我的服务。

POST允许请求,我一直用Postman做测试

此类问题的最常见原因是受众验证问题。观众是 AAD 令牌的 属性,它表示此令牌对什么资源有效。鉴于上面的代码,我希望观众等于 Constants.GraphResourceUri。我的猜测是这实际上是图表 API,而不是您的应用程序,这将导致验证失败,尽管我希望它会在您调用 LoginAsync() 时发生。我建议尝试使用 Web 应用程序客户端 ID(即 "MOBILE SERVICE AUTH SETUP" 屏幕截图中的客户端 ID)。

为了更轻松地进行调试,您可以将 AAD 令牌设为 http://jwt.io 之类的东西,这将有助于您查看令牌属性。 "aud" 应与在门户中注册的应用程序的客户端 ID 相同,并且您希望颁发者字段也匹配。确保令牌也没有过期。

使用令牌访问受保护的API时,有两种提供方式:

  1. 在请求的 X-ZUMO-AUTH header 中使用作为 LoginAsync() 的一部分返回的令牌。对于使用相同 MobileServiceClient 的 table 操作,这将由 SDK 自动完成。
  2. 根据不记名令牌规范直接使用AAD令牌。也就是说,将其包含在授权 header 中,值为 "Bearer ",用您的值替换 token。

此外,我在您的代码中看到您正在为登录操作创建一个新的 MobileServiceClient。我们通常不鼓励这样做,因为登录信息附加到 MobileServiceClient object。如果您丢失了对它的引用,您将丢失登录信息(以及一些其他设置),并且它们将不会应用于您的 table 操作。建议使用在其他地方引用的单个实例 - 例如,在 Xamarin 中,共享代码中的静态变量。