是否支持使用 MSI 的 Azure Function to Function 身份验证

Is Azure Function to Function authentication with MSI supported

我创建了 2 个 Azure Function Apps,都使用 Authentication/Authorization 进行了设置,因此为两者都创建了一个 AD 应用程序。我想使用 MSI 从一个函数设置 AD Auth 到另一个函数。我使用 ARM 模板设置具有托管服务标识的客户端功能。我创建了一个简单的测试函数来获取访问令牌,它 returns: Microsoft.Azure.Services.AppAuthentication: Token response is not in the expected format.

try {
    var azureServiceTokenProvider = new AzureServiceTokenProvider();
    string accessToken = await azureServiceTokenProvider.GetAccessTokenAsync("https://myapp-registration-westus-dev.azurewebsites.net/");
    log.Info($"Access Token: {accessToken}");
    return req.CreateResponse(new {token = accessToken});
}
catch(Exception ex) {
    log.Error("Error", ex);
    throw;
}

请检查使用的资源ID“https://myapp-registration-westus-dev.azurewebsites.net/”是否准确。我按照此处的步骤设置 Azure AD 身份验证,并使用与您相同的代码,并且能够获得令牌。 https://docs.microsoft.com/en-us/azure/app-service/app-service-mobile-how-to-configure-active-directory-authentication

您也可以 运行 此代码来检查 MSI 返回的确切错误。如果错误无助于解决问题,请执行 post 错误。

HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Secret", Environment.GetEnvironmentVariable("MSI_SECRET"));
var response = await client.GetAsync(String.Format("{0}/?resource={1}&api-version={2}", Environment.GetEnvironmentVariable("MSI_ENDPOINT"), "https://myapp-registration-westus-dev.azurewebsites.net/", "2017-09-01"));
string msiResponse = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
log.Info($"MSI Response: {msiResponse}");

更新:- 这个 project.json 文件和 run.csx 文件对我有用。注意:project.json 指的是 .NET 4.6,并且根据 Azure Functions 文档(评论中的 link),.NET 4.6 是目前唯一受支持的版本。 您不需要再次上传引用的程序集。最有可能的是,不正确的手动上传 netstandard 程序集,而不是 net452 导致了您的问题。

Only the .NET Framework 4.6 is supported, so make sure that your project.json file specifies net46 as shown here. When you upload a project.json file, the runtime gets the packages and automatically adds references to the package assemblies. You don't need to add #r "AssemblyName" directives. To use the types defined in the NuGet packages, add the required using statements to your run.csx file.

project.json

{
  "frameworks": {
    "net46":{
      "dependencies": {
        "Microsoft.Azure.Services.AppAuthentication": "1.0.0-preview"
      }
    }
   }
}

run.csx

using Microsoft.Azure.Services.AppAuthentication;

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
    try
    {
        var azureServiceTokenProvider = new AzureServiceTokenProvider();
        string accessToken = await azureServiceTokenProvider.GetAccessTokenAsync("https://vault.azure.net/");
        log.Info($"Access Token: {accessToken}");
        return req.CreateResponse(new {token = accessToken});
    }
    catch(Exception ex) 
    {
        log.Error("Error", ex);
        throw;
    }    
}

是的,有办法做到这一点。我将在高层次上进行解释,然后将一个项目添加到 MSI 文档积压工作中,以为此编写适当的教程。

你想要做的是遵循这个 Azure AD 身份验证示例,但只配置和实现 TodoListService 的部分:https://github.com/Azure-Samples/active-directory-dotnet-daemon

TodoListDaemon 的角色将由托管服务身份代替。因此,您无需按照自述文件中的说明在 Azure AD 中注册 TodoListDaemon 应用程序。只需在 VM/App Service/Function.

上启用 MSI

在您的代码客户端代码中,当您调用 MSI(在 VM 上或在函数或应用服务中)时,提供 TodoListService 的 AppID URI 作为资源参数。 MSI 将为您获取该观众的令牌。

TodoListService 示例中的代码将向您展示如何在收到该令牌时对其进行验证。

所以本质上,您要做的是在 Azure AD 中注册一个应用程序,给它一个 AppID URI,然后在调用 MSI 时使用该 AppID URI 作为资源参数。然后验证您在 service/receiving 端收到的令牌。