【发布时间】:2016-12-15 16:48:50
【问题描述】:
全部,
我正在尝试将组分配给租户中的应用程序(我的公司不拥有该应用程序,Box)。我从下载了 Graph Console App V3 https://github.com/Azure-Samples/active-directory-dotnet-graphapi-console 并查看了代码。我下面的代码似乎遵循了这个例子,唯一的区别是我想把这一切作为应用程序来做,而不需要用户同意。当我尝试在“应用程序模式”下运行控制台应用程序时,它会因权限问题而失败。所以,我只是写了下面的代码,没有遇到权限问题,但又遇到了另一个错误(请参阅我的 cmets inline)。
我使用的是 Java,而不是 .NET,但我想使用 Fiddler 来查看请求是什么,因为我在使用 Java 手动创建请求时运气不佳。
不过,我在使用 Microsoft.Azure.ActiveDirectory.GraphClient 的 .NET 中也没有任何运气。这是我的代码。我的租户有一个单租户公司拥有的应用程序,其应用程序权限授予“Windows Azure Active Directory”。
try
{
var servicePrincipals = await client.ServicePrincipals.ExecuteAsync();
var servicePrincipal = (ServicePrincipal)servicePrincipals.CurrentPage
.SingleOrDefault(sp => sp.AppDisplayName == "Box");
while (servicePrincipal == null && servicePrincipals.MorePagesAvailable)
{
await servicePrincipals.GetNextPageAsync();
servicePrincipal = (ServicePrincipal)servicePrincipals.CurrentPage
.SingleOrDefault(sp => sp.AppDisplayName == "Box");
}
if (servicePrincipal != null)
{
var spfetcher = (servicePrincipal as IServicePrincipalFetcher);
// returns the correct information and all guids align properly with the correct servicePrincipal,
// Id (appRole) and principalId for the group
var appRoleAssignments = await spfetcher.AppRoleAssignedTo.ExecuteAsync();
// data returned by call above
//CreationTimestamp null
//Id {efxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
//PrincipalDisplayName "TestGroup"
//PrincipalId {39xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
//PrincipalType "Group"
//ResourceDisplayName "Box"
//ResourceId {11xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
// I have a group called "Manually Added" that want to assign to this application with
// the first role that the service principal has
var groups = await client.Groups.ExecuteAsync();
var group = (Group)groups.CurrentPage.SingleOrDefault(g => g.DisplayName.Contains("Manual"));
while (group == null && groups.MorePagesAvailable)
{
await groups.GetNextPageAsync();
group = (Group)groups.CurrentPage.SingleOrDefault(g => g.DisplayName.Contains("Manual"));
}
if (group != null)
{
// Tried this way, seems to be correct as far as the documentation and examples
AppRoleAssignment appRoleAssignment = new AppRoleAssignment();
// just use a known appRole id for this example
appRoleAssignment.Id = servicePrincipal.AppRoles.FirstOrDefault().Id;
// the service principal to add the group with the app role
appRoleAssignment.ResourceId = Guid.Parse(servicePrincipal.ObjectId);
// principal is a group (named ManuallyAdded)
appRoleAssignment.PrincipalType = "Group";
// the id of the group (ManuallyAdded)
appRoleAssignment.PrincipalId = Guid.Parse(group.ObjectId);
// Tried this way, no luck Bad Request (400) with "not a valid reference update"
servicePrincipal.AppRoleAssignments.Add(appRoleAssignment);
await servicePrincipal.UpdateAsync();
// Tried this way, same thing as above
//var spfetcher = (servicePrincipal as IServicePrincipalFetcher);
//var appRoleAssignments = await spfetcher.AppRoleAssignedTo.ExecuteAsync();
await spfetcher.AppRoleAssignments.AddAppRoleAssignmentAsync(appRoleAssignment);
// Tried this way, same thing as above
// var groupFetcher = (group as IGroupFetcher);
// await groupFetcher.AppRoleAssignments.AddAppRoleAssignmentAsync(appRoleAssignment);
// Tried flipping the resourceId and the principalId, to assign the app through the group
// AddAppRoleAssignmentAsync. Same error
//appRoleAssignment = new AppRoleAssignment();
//appRoleAssignment.Id = servicePrincipal.AppRoles.FirstOrDefault().Id;
//appRoleAssignment.ResourceId = Guid.Parse(group.ObjectId);
//appRoleAssignment.PrincipalType = "Group";
//appRoleAssignment.PrincipalId = Guid.Parse(servicePrincipal.ObjectId);
//// Tried this way, same thing as above
//var groupFetcher = (group as IGroupFetcher);
//await groupFetcher.AppRoleAssignments.AddAppRoleAssignmentAsync(appRoleAssignment);
}
}
}
catch (Exception e)
{
Program.WriteError("Error: {0}", Program.ExtractErrorMessage(e));
}
在 Azure 中授予的权限:
谢谢! 布赖恩
更新
这是我的访问令牌中的内容
{
"aud": "https://graph.windows.net",
"iss": "https://sts.windows.net/<tenantId>/",
"iat": 1480449285,
"nbf": 1480449285,
"exp": 1480453185,
"appid": "<appId>",
"appidacr": "1",
"e_exp": 10800,
"idp": "https://sts.windows.net/<tenantId>/",
"oid": "xxxxxx-0b62-4d91-8853-xxxxxxxxxxxx",
"roles": [
"Device.ReadWrite.All",
"Directory.Read.All",
"Member.Read.Hidden",
"Directory.ReadWrite.All",
"Domain.ReadWrite.All"
],
"sub": "xxxxxx-0b62-4d91-8853-xxxxxxxxxxxx",
"tid": "<tenantId>",
"ver": "1.0"
}
这是引发权限问题的代码(这是我在上面链接的 graphapi-console 中找到的修改代码),但调用了 GraphRequest.cs 中的现有方法
// the exception occurs in CreateNewApplication.
// But in my case, I have already loaded the existing servicePrincipal
var newApp = await CreateNewApplication(client);
var newServicePrincipal = await CreateServicePrincipal(client, newApp);
await AssignAppRole(client, newApp, newServicePrincipal);
什么原因:
{
"odata.error": {
"code": "Authorization_RequestDenied",
"message": {
"lang": "en",
"value": "Insufficient privileges to complete the operation."
}
}
}
【问题讨论】:
-
您能否分享您的访问令牌中的范围声明“scp”?您还可以在遇到权限问题的流程中分享相同的信息吗?
-
我已更新我的问题以添加访问令牌信息和导致权限异常的请求代码。 @ShawnTabrizi
标签: azure azure-active-directory azure-ad-graph-api