【发布时间】:2019-03-22 09:08:26
【问题描述】:
我目前可以使用 Azure 资源管理器通过 PowerShell(客户端 ID 1950a258-227b-4e31-a9cf-717495945fc2)管理多个 Azure AD 租户中的资源,使用在 Azure AD 和所有 Azure AD 中都具有提升权限的用户帐户使用委派权限相关订阅。即,使用此用户登录的 SubscriptionClient 有一个方法 SubscriptionClient.tenants.List(),如果我有权以该用户身份访问不同租户中的订阅,它将列出多个租户。
我正在编写跨租户自动化,而我正在尝试做的是在 Azure 中使用 .NET 函数来执行上述操作,而无需从某种跨租户上帝用户帐户(作为旧的-学校服务帐户)。相反,我想赋予函数本身权限。
-
第一次尝试 - 使用 MSI:
我想实际上让服务原则存在于 服务原则的非本地租户将使用(换行符以提高可读性):
https://login.microsoftonline.com/{Target_foreign_tenant}/adminconsent ?client_id={id_of_msi} &redirect_uri=http://localhost/myapp/permissions使用管理员帐户并接受权限。这里的问题是 MSI 需要 Graph API 权限才能工作。于是我又试了:
New-AzureADServiceAppRoleAssignment `#` -ObjectId {object_id_of_msi} `#` -PrincipalId {object_id_of_msi} `#` -ResourceId {object_id_of_graph_SP} `#` -Id {permissions_id_of_relevant_graph_role}上述命令以 MSI 服务主体的全局管理员权限运行,会给出如下所示的“权限不足”错误。 (请注意,在应用注册的服务主体上,这工作正常,没有权限问题。)
New-AzureADServiceAppRoleAssignment : Error occurred while executing NewServicePrincipalAppRoleAssignment Code: Authorization_RequestDenied Message: Insufficient privileges to complete the operation. HttpStatusCode: Forbidden HttpStatusDescription: Forbidden HttpResponseStatus: Completed At line:1 char:1 + New-AzureADServiceAppRoleAssignment -Id {where id would be here} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [New-AzureADServiceAppRoleAssignment], ApiException + FullyQualifiedErrorId : Microsoft.Open.AzureAD16.Client.ApiException,Microsoft.Open.AzureAD16.PowerShell.NewServicePrincipalAppRoleAssignment -
然后我放弃了 MSI 并决定使用启用多租户 而是 Web 应用程序注册。我又用了:
https://login.microsoftonline.com/{Target_forgien_ADTenant}/adminconsent ?client_id={id_of_webappreg} &redirect_uri=http://localhost/myapp/permissions成功了!我现在可以在我的外国租户中看到我的应用程序 在“企业应用”下注册,并在 外国 Azure AD 租户并查看服务主体 - 哇!
然后,我兴奋地将我的企业应用所有者权限分配给了一个 在我的外国租户中订阅,并运行我列出的函数 租户和订阅使用顶部的 API。不幸的是,它 与用户不同,仍然只能在其主租户中查看订阅。
对如何使这两种方法发挥作用有任何帮助吗?我的函数如下所示:
public static async Task<SubscriptionClient> GetSubscriptionClient(string clientID, string clientSecret, string tenantName)
{
var serviceCreds = new TokenCredentials(await GetRMAccessToken(clientID, clientSecret, tenantName).ConfigureAwait(false));
return new SubscriptionClient(serviceCreds);
}
public static async Task<string> GetRMAccessToken(string clientID, string clientSecret, string tenantName)
{
var authString = "https://login.microsoftonline.com/" + tenantName;
var resourceUrl = "https://management.azure.com/";
var authenticationContext = new AuthenticationContext(authString, false);
var clientCred = new ClientCredential(clientID, clientSecret);
var authenticationResult = await authenticationContext.AcquireTokenAsync(resourceUrl, clientCred);
var token = authenticationResult.AccessToken;
return token;
}
var subClient = await SubscriptionManagement.GetSubscriptionClient(clientID, clientSecret, tenantName);
var tenants = new List<string>();
foreach(var tenant in subClient.Tenants.List())
{
tenants.Add(tenant.TenantId + " - " + tenant.TenantId);
}
【问题讨论】:
标签: azure azure-devops azure-active-directory azure-functions azure-resource-manager