Azure Active Directory 应用程序服务无法使用用户凭据/令牌连接到 Azure Keyvault

发布于 2025-01-15 07:19:43 字数 6729 浏览 4 评论 0原文

我正在尝试创建一个 Web 应用程序,用户可以在其中探索其 azure 广告帐户明确有权访问的 Azure Keyvault 秘密信息。它本质上是一个 Azure Keyvault 仪表板。当用户登录应用程序时,我使用 Azure Active Directory 身份验证。此应用程序作为 azure 应用程序服务托管。

Azure Active Directory 身份验证本身工作正常,但当我尝试从 Azure 中使用 SecretClientDefaultAzureCredential 连接到 Azure Keyvault 时,它不起作用。

这是我用来收集秘密信息的代码:

var client = new SecretClient(new Uri(this.azureKeyVaultSettings.Value.KeyVaultBaseUrl),
                                      new DefaultAzureCredential(new DefaultAzureCredentialOptions()
                                                                 {
                                                                     ExcludeSharedTokenCacheCredential = false
                                                                 }));
                                                                     
var secrets = client.GetPropertiesOfSecretsAsync();

await foreach (SecretProperties secret in secrets)
{
    ...
}

下面是我在 Startup.cs 中的代码。我觉得我缺少的部分是通过 oidc 登录后返回的令牌的存储,并以某种方式在 SecretClient 中利用它。我起初以为这就是 EnableTokenAcquisitionToCallDownstreamApiAddInMemoryTokenCaches 下面所做的事情,并且 DefaultAzureCredential 会利用它,但这显然不起作用。

public void ConfigureServices(IServiceCollection services)
{
    ...
    
    services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
            .AddMicrosoftIdentityWebApp(this.Configuration,
                                        "AzureAd")
            .EnableTokenAcquisitionToCallDownstreamApi(new string[]
                                                       {
                                                           "user.read"
                                                       })
            .AddInMemoryTokenCaches();
    
    services.AddMvc(options =>
    {
        var policy = new AuthorizationPolicyBuilder()
            .RequireAuthenticatedUser()
            .Build();
        options.Filters.Add(new AuthorizeFilter(policy));
    }).AddMicrosoftIdentityUI();
    
    ...

AppSettings.json:

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "Domain": "mydomain.com",
    "TenantId": "c9db0b8f-****-****-****-************",
    "ClientId": "318b64c3-****-****-****-************",
    "ClientSecret": "vh27Q*********************",
    "CallbackPath": "/signin-oidc"
  },
  "AzureKeyVaultSettings": {
    "KeyVaultBaseUrl": "https://myspecialvault.vault.azure.net/"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

我在天蓝色应用程序服务中遇到的错误是:

2022-03-19 11:32:49.842 +00:00 [Critical] AzureKeyVaultDashboard.Web.Controllers.HomeController: Azure.Identity.CredentialUnavailableException: DefaultAzureCredential failed to retrieve a token from the included credentials. See the troubleshooting guide for more information. https://aka.ms/azsdk/net/identity/defaultazurecredential/troubleshoot
- EnvironmentCredential authentication unavailable. Environment variables are not fully configured. See the troubleshooting guide for more information. https://aka.ms/azsdk/net/identity/environmentcredential/troubleshoot- ManagedIdentityCredential authentication unavailable. Multiple attempts failed to obtain a token from the managed identity endpoint.- SharedTokenCacheCredential authentication unavailable. No accounts were found in the cache.- Visual Studio Token provider can't be accessed at D:\DWASFiles\Sites\myazkvdashboard\LocalAppData\.IdentityService\AzureServiceAuth\tokenprovider.json- Stored credentials not found. Need to authenticate user in VSCode Azure Account. See the troubleshooting guide for more information. https://aka.ms/azsdk/net/identity/vscodecredential/troubleshoot- Azure CLI not installed- PowerShell is not installed.---> System.AggregateException: Multiple exceptions were encountered while attempting to authenticate. (EnvironmentCredential authentication unavailable. Environment variables are not fully configured. See the troubleshooting guide for more information. https://aka.ms/azsdk/net/identity/environmentcredential/troubleshoot) (ManagedIdentityCredential authentication unavailable. Multiple attempts failed to obtain a token from the managed identity endpoint.) (SharedTokenCacheCredential authentication unavailable. No accounts were found in the cache.) (Visual Studio Token provider can't be accessed at D:\DWASFiles\Sites\myazkvdashboard\LocalAppData\.IdentityService\AzureServiceAuth\tokenprovider.json) (Stored credentials not found. Need to authenticate user in VSCode Azure Account. See the troubleshooting guide for more information. https://aka.ms/azsdk/net/identity/vscodecredential/troubleshoot) (Azure CLI not installed) (PowerShell is not installed.)---> Azure.Identity.CredentialUnavailableException: EnvironmentCredential authentication unavailable. Environment variables are not fully configured. See the troubleshooting guide for more information. https://aka.ms/azsdk/net/identity/environmentcredential/troubleshootat Azure.Identity.CredentialDiagnosticScope.FailWrapAndThrow(Exception ex, String additionalMessage)at Azure.Identity.EnvironmentCredential.GetTokenImplAsync(Boolean async, TokenRequestContext requestContext, CancellationToken cancellationToken)at Azure.Identity.EnvironmentCredential.GetTokenAsync(TokenRequestContext requestContext, CancellationToken cancellationToken)at Azure.Identity.DefaultAzureCredential.GetTokenFromSourcesAsync(TokenCredential[] sources, TokenRequestContext requestContext, Boolean async, CancellationToken cancellationToken)--- End of inner exception stack trace ------> (Inner Exception #1) Azure.Identity.CredentialUnavailableException: ManagedIdentityCredential authentication unavailable. Multiple attempts failed to obtain a token from the managed identity endpoint.---> System.AggregateException: Retry failed after 4 tries. Retry settings can be adjusted in ClientOptions.Retry. (An attempt was made to access a socket in a way forbidden by its access permissions. (100.100.100.100:80)) (An attempt was made to access a socket in a way forbidden by its access permissions. (100.100.100.100:80)) (An attempt was made to access a socket in a way forbidden by its access permissions. (100.100.100.100:80)) (An attempt was made to access a socket in a way forbidden by its access permissions. (100.100.100.100:80))

在本地测试时,所有这些功能似乎都工作正常。

我正在使用

  • .net 6
  • Azure.Identity - 1.5
  • Azure.Security.KeyVault.Secrets - 4.2

I'm trying to create a web app where a user can explore Azure Keyvault secret information that their azure ad account explicitly has access to. It's an Azure Keyvault dashboard essentially. I'm using Azure Active Directory authentication when the user signs in to the app. This app is being hosted as an azure app service.

The Azure Active Directory authentication itself is working fine but when I try to connect to Azure Keyvault using the SecretClient and DefaultAzureCredential from within Azure, it's not working.

Here is the code I'm using to gather secret information:

var client = new SecretClient(new Uri(this.azureKeyVaultSettings.Value.KeyVaultBaseUrl),
                                      new DefaultAzureCredential(new DefaultAzureCredentialOptions()
                                                                 {
                                                                     ExcludeSharedTokenCacheCredential = false
                                                                 }));
                                                                     
var secrets = client.GetPropertiesOfSecretsAsync();

await foreach (SecretProperties secret in secrets)
{
    ...
}

Below is the code I have in Startup.cs. I feel like the part I'm missing is the storing of the token I'm getting back after signin via oidc and leveraging that in the SecretClient somehow. I at first thought that's what EnableTokenAcquisitionToCallDownstreamApi and AddInMemoryTokenCaches were doing below and somehow DefaultAzureCredential would leverage that but that is obviously not working.

public void ConfigureServices(IServiceCollection services)
{
    ...
    
    services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
            .AddMicrosoftIdentityWebApp(this.Configuration,
                                        "AzureAd")
            .EnableTokenAcquisitionToCallDownstreamApi(new string[]
                                                       {
                                                           "user.read"
                                                       })
            .AddInMemoryTokenCaches();
    
    services.AddMvc(options =>
    {
        var policy = new AuthorizationPolicyBuilder()
            .RequireAuthenticatedUser()
            .Build();
        options.Filters.Add(new AuthorizeFilter(policy));
    }).AddMicrosoftIdentityUI();
    
    ...

AppSettings.json:

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "Domain": "mydomain.com",
    "TenantId": "c9db0b8f-****-****-****-************",
    "ClientId": "318b64c3-****-****-****-************",
    "ClientSecret": "vh27Q*********************",
    "CallbackPath": "/signin-oidc"
  },
  "AzureKeyVaultSettings": {
    "KeyVaultBaseUrl": "https://myspecialvault.vault.azure.net/"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

The errors I'm getting in my azure app service are:

2022-03-19 11:32:49.842 +00:00 [Critical] AzureKeyVaultDashboard.Web.Controllers.HomeController: Azure.Identity.CredentialUnavailableException: DefaultAzureCredential failed to retrieve a token from the included credentials. See the troubleshooting guide for more information. https://aka.ms/azsdk/net/identity/defaultazurecredential/troubleshoot
- EnvironmentCredential authentication unavailable. Environment variables are not fully configured. See the troubleshooting guide for more information. https://aka.ms/azsdk/net/identity/environmentcredential/troubleshoot- ManagedIdentityCredential authentication unavailable. Multiple attempts failed to obtain a token from the managed identity endpoint.- SharedTokenCacheCredential authentication unavailable. No accounts were found in the cache.- Visual Studio Token provider can't be accessed at D:\DWASFiles\Sites\myazkvdashboard\LocalAppData\.IdentityService\AzureServiceAuth\tokenprovider.json- Stored credentials not found. Need to authenticate user in VSCode Azure Account. See the troubleshooting guide for more information. https://aka.ms/azsdk/net/identity/vscodecredential/troubleshoot- Azure CLI not installed- PowerShell is not installed.---> System.AggregateException: Multiple exceptions were encountered while attempting to authenticate. (EnvironmentCredential authentication unavailable. Environment variables are not fully configured. See the troubleshooting guide for more information. https://aka.ms/azsdk/net/identity/environmentcredential/troubleshoot) (ManagedIdentityCredential authentication unavailable. Multiple attempts failed to obtain a token from the managed identity endpoint.) (SharedTokenCacheCredential authentication unavailable. No accounts were found in the cache.) (Visual Studio Token provider can't be accessed at D:\DWASFiles\Sites\myazkvdashboard\LocalAppData\.IdentityService\AzureServiceAuth\tokenprovider.json) (Stored credentials not found. Need to authenticate user in VSCode Azure Account. See the troubleshooting guide for more information. https://aka.ms/azsdk/net/identity/vscodecredential/troubleshoot) (Azure CLI not installed) (PowerShell is not installed.)---> Azure.Identity.CredentialUnavailableException: EnvironmentCredential authentication unavailable. Environment variables are not fully configured. See the troubleshooting guide for more information. https://aka.ms/azsdk/net/identity/environmentcredential/troubleshootat Azure.Identity.CredentialDiagnosticScope.FailWrapAndThrow(Exception ex, String additionalMessage)at Azure.Identity.EnvironmentCredential.GetTokenImplAsync(Boolean async, TokenRequestContext requestContext, CancellationToken cancellationToken)at Azure.Identity.EnvironmentCredential.GetTokenAsync(TokenRequestContext requestContext, CancellationToken cancellationToken)at Azure.Identity.DefaultAzureCredential.GetTokenFromSourcesAsync(TokenCredential[] sources, TokenRequestContext requestContext, Boolean async, CancellationToken cancellationToken)--- End of inner exception stack trace ------> (Inner Exception #1) Azure.Identity.CredentialUnavailableException: ManagedIdentityCredential authentication unavailable. Multiple attempts failed to obtain a token from the managed identity endpoint.---> System.AggregateException: Retry failed after 4 tries. Retry settings can be adjusted in ClientOptions.Retry. (An attempt was made to access a socket in a way forbidden by its access permissions. (100.100.100.100:80)) (An attempt was made to access a socket in a way forbidden by its access permissions. (100.100.100.100:80)) (An attempt was made to access a socket in a way forbidden by its access permissions. (100.100.100.100:80)) (An attempt was made to access a socket in a way forbidden by its access permissions. (100.100.100.100:80))

All of this functionality appears to work fine when testing locally.

I'm using

  • .net 6
  • Azure.Identity - 1.5
  • Azure.Security.KeyVault.Secrets - 4.2

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

冷弦 2025-01-22 07:19:44

似乎 DefaultAzureCredential 在我的情况下并没有真正起作用。我必须将 ITokenAcquisition 对象注入到我的构造函数中,并使用像这样的 ChainedCredential 而不是仅仅使用 DefaultAzureCredential

var client = new SecretClient(new Uri(this.azureKeyVaultSettings.Value.KeyVaultBaseUrl),
                              new ChainedTokenCredential(new TokenAcquisitionTokenCredential(this.tokenAcquisition),
                                                               new DefaultAzureCredential());

var secrets = client.GetPropertiesOfSecretsAsync();

我还必须添加 < code>https://vault.azure.net/user_impersonation 到 .EnableTokenAcquisitionToCallDownstreamApi() 调用。请参阅下面我原始帖子中的 Startup.cs 更正:

services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
        .AddMicrosoftIdentityWebApp(this.Configuration,
                                    "AzureAd")
        .EnableTokenAcquisitionToCallDownstreamApi(new string[]
                                                   {
                                                       "https://vault.azure.net/user_impersonation",
                                                       "user.read"
                                                   })
        .AddInMemoryTokenCaches();

.EnableTokenAcquisitionToCallDownstreamApi() 允许将 ITokenAcquisition 注入到控制器中。有关更多详细信息,请参阅此处:

https://learn.microsoft.com/en-us/azure/active-directory/develop/scenario-web-app-call-api-app-configuration?tabs=aspnetcore#startupcs

It seems as though the DefaultAzureCredential doesn't really work in my case. I had to inject an ITokenAcquisition object into my constructor and use a ChainedCredential like this instead of just using DefaultAzureCredential:

var client = new SecretClient(new Uri(this.azureKeyVaultSettings.Value.KeyVaultBaseUrl),
                              new ChainedTokenCredential(new TokenAcquisitionTokenCredential(this.tokenAcquisition),
                                                               new DefaultAzureCredential());

var secrets = client.GetPropertiesOfSecretsAsync();

I also had to add the https://vault.azure.net/user_impersonation to the .EnableTokenAcquisitionToCallDownstreamApi() call. See below Startup.cs correction from my original post:

services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
        .AddMicrosoftIdentityWebApp(this.Configuration,
                                    "AzureAd")
        .EnableTokenAcquisitionToCallDownstreamApi(new string[]
                                                   {
                                                       "https://vault.azure.net/user_impersonation",
                                                       "user.read"
                                                   })
        .AddInMemoryTokenCaches();

The .EnableTokenAcquisitionToCallDownstreamApi() is what allows the ITokenAcquisition to be injected in controllers. See here for more detail:

https://learn.microsoft.com/en-us/azure/active-directory/develop/scenario-web-app-call-api-app-configuration?tabs=aspnetcore#startupcs

戏剧牡丹亭 2025-01-22 07:19:44

在部署 keyvault 和应用服务时,您可以使用应用服务的主体 ID 在 keyvault 上设置应用服务的访问策略。这样,应用程序服务下托管的Web应用程序将获得对keyvault的访问权限。
您可以使用 azure ad 身份验证对登录的用户进行身份验证,然后在 Web 应用程序上提供密钥保管库详细信息。

请检查并评论它是否适合您。

On deployment of keyvault and app service, you can set the access policy at keyvault for app service using principal ID of app service. In this way, the web app hosted under app service will get the access to keyvault.
You can use azure ad authentication to authenticate the user logging in and then provide the key vault detail on your web application.

Please check and comment whether it works for you.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文