使用Application Identity访问Azure Graph API

时间:2015-07-22 14:21:41

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

我正在使用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和客户端密钥中获取的。

我的应用具有委派的权限&#34;读取目录数据&#34;和&#34;启用登录并阅读用户的个人资料&#34;。它具有应用程序权限&#34;读取目录数据&#34;和#34;读写目录数据&#34;虽然我并不真正需要后者。但是,这不允许我查询Graph API。所有用户查询,例如

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

抛出错误&#34;没有足够的权限来完成操作&#34;。

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

2 个答案:

答案 0 :(得分:3)

我认为这个问题在目前的形式上是误导性的。您可以以用户身份和应用程序身份获取令牌,并且您可以同时使用AcquireTokenAcquireTokenSilent来执行这两项操作。可以在目录中配置应用程序以请求不同的权限,具体取决于它们是使用其应用程序标识访问资源还是使用用户标识进行委派访问。

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

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

答案 1 :(得分:1)

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

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

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