1

我正在使用 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()

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

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

4

2 回答 2

3

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

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

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

于 2015-07-22T14:56:13.410 回答
1

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

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

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

于 2015-07-24T14:59:23.400 回答