所有
我正在尝试将一个组分配给我的租户中的应用程序(我的公司不拥有,Box)。我从中下载了Graph Console App V3 https://github.com/Azure-Samples/active-directory-dotnet-graphapi-console并查看了代码。我的下面的代码似乎遵循了这个例子,唯一的区别是我想把这一切都作为应用程序而不需要用户同意。当我尝试在“应用程序模式”下运行控制台应用程序时,它失败并出现权限问题。所以,我刚刚编写了下面的代码,没有获得权限问题,但是我收到了另一个错误(请参阅我的内联评论)。
我使用的是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."
}
}
}
答案 0 :(得分:0)
将角色分配给特定组的应用程序。我们需要更新特定的组,而不是应用。以下是您的参考请求:
POST: https://graph.windows.net/xxx.onmicrosoft.com/directoryObjects/{GroupId}/Microsoft.DirectoryServices.Group/appRoleAssignments?api-version=1.6
Authorization: Bearer {token}
{
"id": "{roleId}",
"odata.type":"Microsoft.DirectoryServices.AppRoleAssignment",
"principalId":"{groupId}",
"principalType":"Group",
"resourceId":"{principalId}"
}
要解决有关完成操作的权限不足的403错误,我们需要使用下面的命令,使用Azure ActiveDirectory (MSOnline)分配公司管理员角色申请。
Connect-MsolService
$ClientIdWebApp = '{your_AD_application_client_id}'
$webApp = Get-MsolServicePrincipal –AppPrincipalId $ClientIdWebApp
#use Add-MsolRoleMember to add it to "Company Administrator" role).
Add-MsolRoleMember -RoleName "Company Administrator" -RoleMemberType ServicePrincipal -RoleMemberObjectId $webApp.ObjectId
答案 1 :(得分:0)
以下是我最终提出的完整答案。
用于创建appRoleAssignment:
private static final String RESOURCE_BASE_URL = "https://graph.windows.net";
private static final String GROUPS_RESOURCE_SET = "groups";
private static final String PRINCIPAL_TYPE = "Group";
// use this if you want to assign a User
// private static final String PRINCIPAL_TYPE = "User";
private static final String API_VERSION = "api-version=1.6";
private String tenantName = "<your tenant name (domain) or id>"
private String appRoleId = "<some appRoleId (from the applications appRoles list or Empty UUID>"
private String servicePrincipalId = "<your servicePrincipalId for the assignment>"
private String principalId = "<your user or group id>"
// empty UUID for appRoleId means no app roles initially (default access)
String postData = String.format(
"{\n" +
"\"id\": \"%s\"," +
"\"principalId\": \"%s\"," +
"\"principalType\": \"%s\"," +
"\"resourceId\": \"%s\"" +
"}", appRoleId, principalId,
PRINCIPAL_TYPE, servicePrincipalId);
String urlString = String.format("%s/%s/%s/%s/appRoleAssignments?%s", RESOURCE_BASE_URL,
tenantName, GROUPS_RESOURCE_SET, <group objectId>, API_VERSION);
在我的租户上以编程方式创建应用程序的权限问题令人困惑。经过大量的搜索后,应用程序(服务主体)似乎需要具有公司管理员角色(或具有足够权限的角色)。我无法通过门户网站或AD Graph API进行此操作,但可能有办法实现此目的。相反,您似乎必须使用Powershell脚本。我在几个地方(不同的版本)在网上找到了这个,经过一些试验和错误后,将其缩小到这个范围。
# -------------------------------
# Connect and request credentials
# --------------------------------
Connect-MsolService
# ------------------------------------------------
# Get the service principal objectId for the specified app
# -----------------------------------------------
$appDisplayName = "<your app name>"
$objectId = (Get-MsolServicePrincipal -SearchString $appDisplayName).ObjectId
# ------------------------------------------------
# Assign the company admin role to the service principal
# -----------------------------------------------
$tenantRoleName = "Company Administrator"
Add-MsolRoleMember -RoleName $tenantRoleName -RoleMemberType ServicePrincipal -RoleMemberObjectId $objectId
安装哪个模块有点令人困惑。我确切地追踪了获得正确cmdlet所需的内容。似乎MSOnline模块提供了运行此脚本所需的一切。如果没有,请安装AzureAD模块(或AzureADPreview moldule),如果出现错误。这些是我找到的最佳步骤:https://docs.microsoft.com/en-us/powershell/msonline/
布赖恩