7

我创建了 2 个 Azure 函数应用程序,都设置了身份验证/授权,因此为两者创建了一个 AD 应用程序。我想使用 MSI 将 AD Auth 从一个功能设置到另一个功能。我使用 ARM 模板使用托管服务标识设置客户端功能。我创建了一个简单的测试函数来获取访问令牌并返回:Microsoft.Azure.Services.AppAuthentication: 令牌响应不是预期的格式。

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;
}
4

2 回答 2

2

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

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

TodoListDaemon 的角色将由托管服务身份代替。因此,您无需按照自述文件中的说明在 Azure AD 中注册 TodoListDaemon 应用。只需在您的 VM/应用服务/功能上启用 MSI。

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

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

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

于 2017-10-11T16:45:42.243 回答
1

请检查使用的资源 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 返回的确切错误。如果它不能帮助解决问题,请发布错误。

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 文档(评论中的链接),.NET 4.6 是目前唯一受支持的版本。您无需再次上传引用的程序集。最有可能的是,不正确的手动上传 netstandard 程序集,而不是 net452 会导致您的问题。

仅支持 .NET Framework 4.6,因此请确保您的 project.json 文件指定 net46,如此处所示。当您上传 project.json 文件时,运行时会获取包并自动添加对包程序集的引用。您不需要添加 #r "AssemblyName" 指令。若要使用 NuGet 包中定义的类型,请将所需的 using 语句添加到 run.csx 文件中。

项目.json

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

运行.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;
    }    
}
于 2017-10-04T21:45:05.700 回答