4

我在 Azure 中有一个函数,它启用了 MSI(托管服务标识),我试图用它来访问基于 Azure 的 WebAPI(应用服务 WebApp),而后者又启用了 Azure AD 身份验证(所有相同的 Azure 目录)。

我的 WebAPI 注册了一个 Azure 应用程序,因此它可以使用 AAD 身份验证。

此应用程序还在其清单中配置了必要的 AppRoles(用于类型“用户”和“应用程序”)。

当我在函数上启用 MSI 时,我还验证了函数标识(应用程序)已在 Azure AD 中成功创建。

当我尝试使用 MSI 在我的函数中获取令牌时,我收到 400 Bad Request 响应/错误:

“ExceptionMessage”:“AADSTS50105:应用程序‘###’未分配给应用程序‘###’的角色

“错误代码”:“invalid_grant”

我已确保我传入的资源值是我的 webAPIs 应用程序 ID URI。

string resource = "<My App URI>";
string apiversion = "2017-09-01";
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Secret", Environment.GetEnvironmentVariable("MSI_SECRET"));
var r = await client.GetAsync(String.Format("{0}/?resource={1}&api-version={2}", Environment.GetEnvironmentVariable("MSI_ENDPOINT"), resource, apiversion));
return r;

但我仍然得到同样的错误。请求令牌的代码很好,错误确实指向权限问题。

我无法做的一件事(我猜这是问题所在)是找到一种方法将新的 MSI/功能标识添加到 webAPIs Azure App 的用户和组。无论我尝试什么,当我搜索它以添加为 webAPI 应用程序的成员(具有应用程序角色)时,我的 Functions App Identity 都不会出现在用户列表中。

有人对我为什么不能将 Functions MSI 添加到应用程序用户和组或 Azure AD 组有任何建议吗?

还是我做错了什么?

4

2 回答 2

2

Juuna在他我原来的帖子的回复中很到位:

在服务上启用 MSI 时,仅在 Azure AD 中创建服务主体,因此在尝试将 SP 添加为组成员或 Azure AD 应用程序的用户和组时,不会出现在搜索结果中。

为了将您创建的 MSI 服务主体权限分配给您的应用程序,您需要:

  1. 编辑您的应用清单并确保您具有允许成员类型 =“应用程序”的应用角色
  2. 运行 PowerShell cmdlet "New-AzureADServiceAppRoleAssignment ( link ) 以向您的服务主体授予您添加到应用清单的应用程序角色
  3. Within your MSI enabled service re-try requesting a token

For me, following the above, I can now successfully request app tokens from my Function so my same Azure Function can call my WebApp (which is AAD Authentication enabled).

于 2018-04-05T12:20:01.913 回答
1

事实上,当您启用 MSI 时,它会创建一个服务主体(不是用户),因此您在用户和组中找不到它。

您可以在 Azure 门户上找到它并尝试授予您需要的权限。Azure Active Directory-->Enterprise applications

在此处输入图像描述

注意:服务主体名称与您的函数名称相同。

在功能上,您应该使用以下代码获取令牌,请参考此链接

using Microsoft.Azure.Services.AppAuthentication;
using Microsoft.Azure.KeyVault;
// ...
var azureServiceTokenProvider = new AzureServiceTokenProvider();
string accessToken = await azureServiceTokenProvider.GetAccessTokenAsync("https://management.azure.com/");
// OR
var kv = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback));
于 2018-04-05T06:22:15.250 回答