2017-10-04 153 views
0

我创建了2个Azure功能应用程序,这两个应用程序都使用身份验证/授权进行设置,因此为两者都创建了AD应用程序。我想使用MSI将AD Auth从一个功能设置到另一个功能。我使用ARM模板将Managed Service Identity设置为客户端功能。我创建了一个简单的测试函数来获取访问令牌,并返回:Microsoft.Azure.Services.AppAuthentication:令牌响应的格式不符合要求。Azure功能支持MSI的功能验证

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

回答

0

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

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

TodoListDaemon的角色将由托管服务标识代替。因此,您无需按照自述文件中的说明在Azure AD中注册TodoListDaemon应用程序。只需在您的虚拟机/应用程序服务/功能上启用MSI即可。

在您的代码客户端代码中,当您调用MSI(在虚拟机或函数或应用程序服务中)时,请提供TodoListService的AppID URI作为资源参数。 MSI会为您为该受众获取一个令牌。

TodoListService示例中的代码将告诉您如何在接收到该令牌时验证该令牌。

所以,基本上,你想要做的是在Azure AD中注册一个App,给它一个AppID URI,并且在你打电话给MSI时使用该AppID URI作为资源参数。然后验证您在服务/接收方收到的令牌。

0

确认所使用的资源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 包中定义的类型,请将所需的使用语句添加到run.csx文件中。

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; 
    }  
} 
+0

“Microsoft.Azure.Services.AppAuthentication”:“1.0.0-preview”, –

+0

使用具有相同资源的client.GetAsync()函数返回一个有效的标记。在Azure函数中,我使用NuGet来解析AppAuthentication组件并使用#r“.. \ bin \ ...”引用。我使用这个参考:**“Microsoft.Azure.Services.AppAuthentication”:“1.0.0-preview”**这是最新版本吗?此外,对该函数进行后续调用会导致GetAccesstokenAsync()挂起并永远不会返回。 –

+0

你可以请分享你从client.GetAsync()获得的响应 - “MSI响应”得到记录?请用占位符替换访问令牌(例如“eyJ0eXAi ...”)。只是想确保响应格式符合预期。 NuGet版本是正确的,这是唯一的版本。 –