【问题标题】:Accessing the Azure Graph API using Application Identity使用应用程序标识访问 Azure Graph API
【发布时间】:2015-07-31 03:38:26
【问题描述】:

我正在使用 Azure Graph API,我注意到我无法读取通过许可框架注册的目录。

一切都适用于用户级权限。也就是说,与

private async Task<string> AcquireGraphApiTokenAsync(string objectId, AuthenticationContext authContext)
{
    var result = await authContext.AcquireTokenSilentAsync(
        GraphUrl, _clientCredential, new UserIdentifier(objectId, UserIdentifierType.UniqueId));
    return result.AccessToken;
}

我可以读取客户端数据如下:

var authority = string.Format(CultureInfo.InvariantCulture, AadInstance, tenantId);
var authContext = new AuthenticationContext(authority, new TokenDbCache(userObjectId));
var graphServiceRoot = GraphUrl + '/' + tenantId;
var graphClient = new ActiveDirectoryClient(new Uri(graphServiceRoot), async () => await AcquireGraphApiTokenAsync(userObjectId, authContext));
try
{
    var adUser = await graphClient.Me.ExecuteAsync();
    ...
}

但是,有时我想在守护进程中运行类似的进程,这就是我遇到麻烦的地方。在这种情况下,我需要使用我的应用程序身份:

private void AuditDirectories(ClientCredential clientCredential, IEnumerable<AzureActiveDirectory> directories)
{
    foreach (var directory in directories)
    {
        var authContext = new AuthenticationContext(string.Format(CultureInfo.InvariantCulture, AadInstance, directory.Domain));
        var result = authContext.AcquireToken(GraphUrl, clientCredential);
        var graphServiceRoot = string.Format("{0}/{1}", GraphUrl, directory.TenantId);
        var graphClient = new ActiveDirectoryClient(new Uri(graphServiceRoot), () => Task.FromResult(result.AccessToken));
        foreach (var user in _userQuery.Office365Users(directory))
        {
            CheckThatAccountExistsAndIsEnabled(graphClient, user);
        }
    }
}

传入的clientCredential 参数是从我的多租户应用程序的客户端 ID 和客户端密码中获取的。

我的应用具有“读取目录数据”和“启用登录和读取用户配置文件”的委派权限。它具有应用程序权限“读取目录数据”和“读取和写入目录数据”,尽管我并不真正需要后者。但是,这不允许我查询 Graph API。所有用户查询,例如

graphClient.Users.Where(u => u.DisplayName == userName).ExecuteAsync().Result.CurrentPage.FirstOrDefault()

抛出错误“权限不足,无法完成操作”。

看起来使用用户身份的委派访问没有任何问题,但使用应用程序身份的访问失败,尽管我已在应用程序级别设置应用程序权限。

【问题讨论】:

    标签: azure-active-directory azure-ad-graph-api


    【解决方案1】:

    我认为这个问题目前的形式具有误导性。您既可以作为用户也可以作为应用程序身份获取令牌,并且您可以同时使用AcquireTokenAcquireTokenSilent 来完成这两件事。可以在目录中配置应用程序以请求不同的权限,具体取决于它们是使用其应用程序身份访问资源还是使用用户身份作为委托访问。

    在您的示例中,您作为AcquireTokenSilent 调用中的用户和AcquireToken 中的应用程序获取令牌,并且您在应用程序中为这两种情况配置的不同权限导致您的行为不同观察到的。但是,这种差异取决于您使用的重载,而不是 AcquireTokenSilentAcquireToken 之间的任何固有差异。

    您可以将应用程序配置为通过门户中的应用程序权限下拉菜单(而不是委托的权限)访问 Azure AD Graph API,但请注意,您需要成为租户管理员才能访问这样做。

    【讨论】:

    • 谢谢。在应用程序权限下拉列表中,检查了两个选项(读取和读写),所以我不明白为什么会出现这种行为。
    • 抱歉,我没有注意到您正在使用 Me 端点。应用程序没有我...您的查询要求提供应用程序没有的用户属性。
    • 请原谅我——我并没有真正这样做。我将编辑问题。
    • 已编辑问题以提供更多信息。感谢您的反馈 - 我还编辑了问题以反映这一点。
    • @vibronet 你能告诉我如何配置守护程序应用程序以使用应用程序身份的示例吗?我有一个以用户身份获取令牌的网络应用程序,但这对我运行更长时间的守护进程没有帮助。
    【解决方案2】:

    这似乎无缘无故地开始工作。虽然我很想说这是魔法发生的,但可能还有另一种解释。

    正如 vibronet 解释的那样,您需要向应用程序添加应用程序权限。完成此操作后,租户管理员需要再次签署同意框架。我在一个单独的浏览器中执行此操作,作为应用程序应该读取其目录的租户的管理员。但是,我在设置应用程序权限后的几分钟内就这样做了。一天后,当我再次通过同意框架时,该应用程序再次开始工作。

    如果您遇到与我描述的情况类似的情况,并且您需要更改应用程序权限下拉菜单,请在您的租户通过同意框架之前给它几分钟传播。 (我假设您将拥有至少一个您是管理员的客户端租户,以便您可以测试您的应用。)

    【讨论】:

    • 在您的其他租户(作为管理员)中同意时 - 让我们将此称为您的测试租户,您是说在同意和能够使用应用程序调用图形之间存在一些延迟(在应用程序中)唯一模式)?我会仔细检查一下 - 显然这种行为是不可取的。
    • 嗨,丹——不,在同意和能够使用图形 API 之间从来没有任何延迟。这一直是瞬间的。在我的 Azure 门户中更改应用程序权限下拉列表后会发生延迟(如果有的话——这只是猜测)。请放心,当我们的客户通过同意框架时,他们可以毫不拖延地使用我们的应用程序。
    • 谢谢罗伯。这里可能存在复制延迟,在管理门户中设置您的应用所需的权限范围,然后在同意对话框中查看这些权限之间。这种延迟在最坏的情况下不应超过几分钟。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-31
    • 1970-01-01
    • 2020-07-21
    相关资源
    最近更新 更多