使用MSI的Azure功能 - 错误请求令牌

时间:2018-04-04 17:50:20

标签: function azure authentication azure-functions service-principal

我在Azure中有一个功能,它启用了MSI(托管服务标识),我尝试使用它来访问基于Azure的WebAPI(App Service WebApp),后者又启用了Azure AD身份验证(所有相同的Azure目录)

我的WebAPI已注册Azure应用,因此可以使用AAD身份验证。

此应用程序还具有在其清单中配置的必要AppRoles(用于类型'用户'以及用于'应用程序')。

我还验证了当我在功能上启用MSI时,在Azure AD中成功创建了功能标识(app)。

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

  

" ExceptionMessage":" AADSTS50105:应用程序' ###'未分配给应用程序的角色' ###'

     

" ErrorCode":" invalid_grant"

我确保传入的资源值是我的webAPIs应用ID ID。

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应用程序的成员(具有应用程序角色)时,App Identity Identity不会出现在用户列表中。

有没有人建议为什么我不能将功能MSI添加到Apps用户&amp;组或Azure AD组?

或者我也许做错了什么?

2 个答案:

答案 0 :(得分:1)

Juunaresponse的原始帖子中出现了:

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

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

  1. 编辑您的应用清单,并确保您拥有允许的成员类型=“应用”
  2. 的应用角色
  3. 运行PowerShell cmdlet“New-AzureADServiceAppRoleAssignment(link)以向您的服务主体授予您添加到应用清单中的应用程序角色
  4. 在启用MSI的服务中重试请求令牌
  5. 对我来说,按照上面的说法,我现在可以从我的功能成功请求应用程序令牌,这样我的同一个Azure功能就可以调用我的WebApp(启用AAD身份验证)。

答案 1 :(得分:0)

事实上,当您启用MSI时,它将创建服务主体(而非用户),因此您无法在用户和组中找到它。

您可以在Azure Portal上找到它并尝试提供所需的权限。 Azure Active Directory - &gt; Enterprise applications

enter image description here

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

在功能方面,您应该使用以下代码获取令牌,请参阅此link

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));