我们需要从Azure App Services和Azure Functions访问Azure Service Bus(ASB)的运行应用程序。我们需要使用用户分配的身份进行身份验证。我们编写以下代码,这些代码适用于系统分配的身份,但不适用于用户分配的身份:
var tokenProvider = TokenProvider.CreateManagedIdentityTokenProvider();
var managementClient = new ManagementClient(serviceBusEndpoint, tokenProvider);
if(await managementClient.QueueExistsAsync(queueName))
{
return new OkObjectResult($"Queue with name {queueName} exists.");
}
else
{
return new OkObjectResult($"Queue with name {queueName} doesn't exist.");
}
抛出此错误:
Microsoft.Azure.Services.AppAuthentication.AzureServiceTokenProviderException: Parameters: Connection String: [No connection string specified], Resource: https://servicebus.azure.net/, Authority: . Exception Message: Tried the following 3 methods to get an access token, but none of them worked.
Parameters: Connection String: [No connection string specified], Resource: https://servicebus.azure.net/, Authority: . Exception Message: Tried to get token using Managed Service Identity. Access token could not be acquired. MSI ResponseCode: BadRequest, Response: {"StatusCode":400,"Message":"No MSI found for specified ClientId/ResourceId.","CorrelationId":"dd2bcf6c-6f1d-489e-b178-ca6007502841"}
Parameters: Connection String: [No connection string specified], Resource: https://servicebus.azure.net/, Authority: . Exception Message: Tried to get token using Visual Studio. Access token could not be acquired. Visual Studio Token provider file not found at "D:\local\LocalAppData\.IdentityService\AzureServiceAuth\tokenprovider.json"
Parameters: Connection String: [No connection string specified], Resource: https://servicebus.azure.net/, Authority: . Exception Message: Tried to get token using Azure CLI. Access token could not be acquired. 'az' is not recognized as an internal or external command,
operable program or batch file.
at Microsoft.Azure.Services.AppAuthentication.AzureServiceTokenProvider.GetAccessTokenAsyncImpl(String authority, String resource, String scope)
at Microsoft.Azure.Services.AppAuthentication.AzureServiceTokenProvider.GetAccessTokenAsync(String resource, String tenantId)
at Microsoft.Azure.ServiceBus.Primitives.ManagedIdentityTokenProvider.GetTokenAsync(String appliesTo, TimeSpan timeout)
at Microsoft.Azure.ServiceBus.Management.ManagementClient.GetToken(String requestUri)
at Microsoft.Azure.ServiceBus.Management.ManagementClient.SendHttpRequest(HttpRequestMessage request, CancellationToken cancellationToken)
at Microsoft.Azure.ServiceBus.Management.ManagementClient.GetEntity(String path, String query, Boolean enrich, CancellationToken cancellationToken)
at Microsoft.Azure.ServiceBus.Management.ManagementClient.GetQueueAsync(String queuePath, CancellationToken cancellationToken)
at Microsoft.Azure.ServiceBus.Management.ManagementClient.QueueExistsAsync(String queuePath, CancellationToken cancellationToken)
所以核心错误是No MSI found for specified ClientId/ResourceId.
。看起来我们需要指定客户端ID。然后,我们发现https://github.com/Azure/azure-sdk-for-net/tree/master/sdk/identity/Azure.Identity与ManagedIdentityCredential
可以在其中指定客户端ID,但尚未弄清楚如何将其用于ASB。
其他选项正在使用对MSI_ENDPOINT的HTTP GET请求,如此处https://docs.microsoft.com/en-us/azure/app-service/overview-managed-identity?context=azure%2Factive-directory%2Fmanaged-identities-azure-resources%2Fcontext%2Fmsi-context&tabs=dotnet#obtaining-tokens-for-azure-resources所述,但可能是我们错过的真实的.net库。
答案 0 :(得分:3)
我在Azure SDK团队中。我们正在https://aka.ms/azsdkpackages处统一所有Azure SDK,但还没有新的Service Bus SDK。
我还没有尝试使用TokenProvider API进行用户分配的身份,但是我知道它可以与新的DefaultAzureCredential对象一起使用,该对象将在您的环境中搜索凭据,并自动获取Managed Identity端点。您可以在这里了解更多信息:https://docs.microsoft.com/en-us/dotnet/api/azure.identity.defaultazurecredential?view=azure-dotnet
但是,由于ServiceBus接受ITokenProvider,因此不能直接使用DefaultAzureCredential。
同时,您可以使用我创建的此适配器-在我们拥有Service Bus SDK之前,这只是权宜之计。
将Azure.Identity和Azure.Core nuget程序包添加到您的项目中。
将此文件复制到您的项目中: https://github.com/jongio/azidext/blob/master/net/JonGallant.Azure.Identity.Extensions/DefaultAzureServiceBusCredential.cs
您可以使用以下环境变量设置客户端ID,机密和租户ID:
AZURE_CLIENT_ID
AZURE_CLIENT_SECRET
AZURE_TENANT_ID
如果您必须使用TokenProvider而又不想使用权宜之计,请告诉我,我可以对其进行进一步研究。
答案 1 :(得分:2)
TokenProvider.CreateManagedIdentityTokenProvider依赖于Microsoft.Azure.Services.AppAuthentication来实现托管身份。
Microsoft.Azure.Services.AppAuthentication的1.2.1版支持用户分配的受管身份。可以找到文档here。
因此,您必须做两件事,以使其与已经拥有的代码一起使用:
1。将Microsoft.Azure.Services.AppAuthentication的版本更新为最新版本
2。在AppService的App设置中将 AzureServicesAuthConnectionString 设置为RunAs = App; AppId = {用户分配的身份的ClientId}。例如RunAs = App; AppId = 587f16c8-81ed-41c7-b19a-9ded0dbe2ca2
完成这两个步骤后,您的代码应使用用户分配的托管身份。我通过应用服务对其进行了尝试,对我来说效果很好。
答案 2 :(得分:0)
截止到今天,我们可以为用户分配以下代码。
var managedCredential = new ManagedIdentityCredential(userAssignedIdentityAppId);
var accessToken = await _managedCredential.GetTokenAsync(
new TokenRequestContext(
new[] { "https://servicebus.azure.net" })).ConfigureAwait(false);
它也可以与"https://servicebus.azure.net/.default"
一起使用。