将 Azure 托管标识用于应用服务未授权新 SDK

Using Azure managed identity for App Service not authorising for new SDK

我们已经成功使用 Microsoft.Azure.KeyVault 一段时间了。在我们的 WebApps 和 AD 组中使用托管标识来授予对密钥保管库的访问权限。

我已经更新了几个应用程序以使用 Azure.Identity 包并且 .Net Framework 应用程序继续运行,但 .Net Core 3.1 应用程序现在似乎没有获取凭据。

如果我添加与 RBAC 生成的服务原则相对应的显式 AZURE_CLIENT_IDAZURE_CLIENT_SECRETAZURE_TENENT_ID,则一切正常。我不想这样做,但更愿意使用托管身份(没有浮动配置)。

这些是我现在引用的包:

<PackageReference Include="Azure.Identity" Version="1.1.1" />
<PackageReference Include="Azure.Security.KeyVault.Secrets" Version="4.0.3" />

这是构造代码:

new SecretClient("name-of-vault", new DefaultAzureCredential());

没什么特别的。

这是堆栈跟踪:

---> Azure.Identity.AuthenticationFailedException: DefaultAzureCredential 身份验证失败。 ---> Azure.Identity.AuthenticationFailedException: 无效响应,身份验证响应不是预期格式。 在 Azure.Identity.ManagedIdentityClient.Deserialize(JsonElement json) 在 Azure.Identity.ManagedIdentityClient.DeserializeAsync(流内容,CancellationToken cancellationToken) 在 Azure.Identity.ManagedIdentityClient.AuthenticateAsync(String[] 范围,CancellationToken cancellationToken) 在 Azure.Identity.ManagedIdentityCredential.GetTokenImplAsync(TokenRequestContext requestContext,CancellationToken cancellationToken) --- 内部异常堆栈跟踪结束 --- 在 Azure.Identity.DefaultAzureCredential.GetTokenAsync(布尔 isAsync,TokenRequestContext requestContext,CancellationToken cancellationToken) 在 Azure.Identity.DefaultAzureCredential.GetTokenAsync(TokenRequestContext requestContext,CancellationToken cancellationToken) 在 Azure.Security.KeyVault.ChallengeBasedAuthenticationPolicy.AuthenticateRequestAsync(HttpMessage 消息、布尔异步、AuthenticationChallenge 挑战) 在 Azure.Security.KeyVault.ChallengeBasedAuthenticationPolicy.ProcessCoreAsync(HttpMessage 消息,ReadOnlyMemory1 管道,布尔异步)在 Azure.Core.Pipeline.RetryPolicy.ProcessAsync(HttpMessage 消息,ReadOnlyMemory1 管道,布尔异步) 在 Azure.Core.Pipeline.RetryPolicy.ProcessAsync(HttpMessage 消息,ReadOnlyMemory1 管道,布尔异步)在 Azure.Core.Pipeline.HttpPipelineSynchronousPolicy.ProcessAsync(HttpMessage 消息,ReadOnlyMemory1 管道) 在Azure.Core.Pipeline.HttpPipelineSynchronousPolicy.ProcessAsync(HttpMessage 消息,ReadOnlyMemory1 管道)在Azure.Core.Pipeline.HttpPipeline.SendRequestAsync(请求请求,CancellationToken cancellationToken)在Azure.Security.KeyVault.KeyVaultPipeline.SendRequestAsync(请求请求,CancellationToken cancellationToken)在Azure.Security.KeyVault.KeyVaultPipeline.SendRequestAsync[TResult](RequestMethod方法,Func1 resultFactory,CancellationToken cancellationToken,String[] 路径) 在 Azure.Security.KeyVault.Secrets.SecretClient.GetSecretAsync(字符串名称、字符串版本、CancellationToken cancellationToken) 在 Codat.Infrastructure.SecretsProvider.SecretsProvider.<>c__DisplayClass18_0.d.MoveNext()

不应该是这样吗?

 var sc = new SecretClient(new Uri("https://<YOUR-KEY-VAULT>.vault.azure.net/"), new DefaultAzureCredential());
 Secret1 = sc.GetSecret(nameof("name-of-vault")).Value;

尝试直接使用ManagedIdentityCredential

new SecretClient(new Uri(kvUri), new ManagedIdentityCredential());

应用服务实例中的 MSI 服务似乎返回了无效的 DateTimeOffset 格式。

要求:

$response = Invoke-WebRequest -Uri 'http://127.0.0.1:41601/MSI/token/?api-version=2017-09-01&resource=https://vault.azure.net' -Method GET -Headers @{Metadata="true";Secret="REDACTED"} -UseBasicParsing

回复:

StatusCode        : 200
StatusDescription : OK
Content           : {123, 34, 97, 99...}
RawContent        : HTTP/1.1 200 OK
                    Content-Length: 1698
                    Date: Mon, 22 Jun 2020 09:26:44 GMT
                    
                    {"access_token":"REDACTED...
Headers           : {[Content-Length, 1698], [Date, Mon, 22 Jun 2020 09:26:44 
                    GMT]}
RawContentLength  : 1698

{
    "access_token": "REDACTED",
    "expires_on": "6/23/2020 9:28:43 AM +00:00",
    "resource": "https://vault.azure.net",
    "token_type": "Bearer",
    "client_id": "E7B39A52-REDACTED"
}

格式 "M/d/yyyy H:m:s tt K" 无法被 ManagedIdentityClient 解析。因此,该错误似乎存在于底层的 azure 服务中。我向团队提出了一个问题 https://github.com/Azure/azure-sdk-for-net/issues/12869 它已在 1.2.0-preview-4 中修复。