为容器化ASP.NET Core 6 Web应用添加Azure Key Vault遇认证问题
容器化ASP.NET Core 6应用访问Azure Key Vault认证失败问题解决
问题描述
本地运行容器化的ASP.NET Core 6 Web应用正常(推测使用Visual Studio凭据),但启动容器时认证失败,提示容器内未安装Az.Account模块。已完成应用注册并持有有效的Azure Client Secret,相关代码与配置如下:
Program.cs代码
public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureAppConfiguration((_, config) => { var root = config.Build(); var vaultName = root["KeyVault:Vault"]; if (!string.IsNullOrEmpty(vaultName)) { var secretClient = new SecretClient( new Uri(vaultName), new DefaultAzureCredential()); config.AddAzureKeyVault(secretClient, new KeyVaultSecretManager()); } }) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); });
Dockerfile内容
FROM mcr.microsoft.com/dotnet/nightly/sdk:6.0 AS base WORKDIR /app EXPOSE 80 EXPOSE 443 FROM mcr.microsoft.com/dotnet/nightly/sdk:6.0 AS build WORKDIR /src ARG PAT RUN wget -qO- https://raw.githubusercontent.com/Microsoft/artifacts-credprovider/master/helpers/installcredprovider.sh | bash ENV NUGET_CREDENTIALPROVIDER_SESSIONTOKENCACHE_ENABLED true ENV DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER=0 ENV VSS_NUGET_EXTERNAL_FEED_ENDPOINTS "{\"endpointCredentials\": [{\"endpoint\":\"https://pkgs.dev.azure.com/.../nuget/v3/index.json\", \"password\":\"${PAT}\"}]}" ARG AspNetCoreEnvironment ENV ASPNETCORE_ENVIRONMENT ${AspNetCoreEnvironment} ARG AzureTenantId ENV AZURE_TENANT_ID ${AzureTenantId} ARG AzureClientId ENV AZURE_CLIENT_ID ${AzureClientId} ARG AzureClientSecret ENV AZURE_CLIENT_SECRET ${AzureClientSecret} COPY . . COPY ["Service/Service.csproj", "Service/"] RUN dotnet restore "Service/Service.csproj" COPY . . WORKDIR "/src/Service" RUN dotnet build "Service.csproj" -c Release -o /app/build FROM build AS publish RUN dotnet publish "Service.csproj" -c Release -o /app/publish FROM base AS final WORKDIR /app COPY --from=publish /app/publish . ENTRYPOINT ["dotnet", "Service.dll"]
构建与启动命令
docker build . -t tag_name --build-args (dockerfile中定义的参数) docker run tag_name
错误信息
Unhandled exception. Azure.Identity.CredentialUnavailableException: The ChainedTokenCredential failed to retrieve a token from the included credentials. - 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. - Operating system Linux 5.4.72-microsoft-standard-WSL2 #1 SMP Wed Oct 28 23:40:43 UTC 2020 isn't supported. - Azure CLI not installed - Az.Account module >= 2.2.0 is not installed. - EnvironmentCredential authentication unavailable. Environment variables are not fully configured. See the troubleshooting guide for more information. https://aka.ms/azsdk/net/identity/environmentcredential/troubleshoot
解决方案
1. 修正环境变量传递逻辑
当前Dockerfile的Azure认证环境变量仅在build阶段设置,而final阶段基于base镜像构建,未继承这些变量,导致EnvironmentCredential无法读取认证信息。需将环境变量配置移至final阶段:
修改后的final阶段代码:
FROM base AS final WORKDIR /app # 传递Azure认证所需环境变量 ARG AzureTenantId ENV AZURE_TENANT_ID ${AzureTenantId} ARG AzureClientId ENV AZURE_CLIENT_ID ${AzureClientId} ARG AzureClientSecret ENV AZURE_CLIENT_SECRET ${AzureClientSecret} # 传递其他必要环境变量 ARG AspNetCoreEnvironment ENV ASPNETCORE_ENVIRONMENT ${AspNetCoreEnvironment} COPY --from=publish /app/publish . ENTRYPOINT ["dotnet", "Service.dll"]
2. 无需安装Az.Account模块
错误中提到的Az.Account模块是PowerShell Azure模块,DefaultAzureCredential会依次尝试多种认证方式,包括PowerShell凭据,但我们仅需确保EnvironmentCredential正常工作即可。解决环境变量问题后,认证会自动使用Client Secret方式,无需额外安装模块。
3. 简化Program.cs配置(可选)
可直接使用AddAzureKeyVault扩展方法,无需手动创建SecretClient,代码更简洁:
public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureAppConfiguration((context, config) => { var configuration = config.Build(); var vaultUri = configuration["KeyVault:Vault"]; if (!string.IsNullOrEmpty(vaultUri)) { config.AddAzureKeyVault( new Uri(vaultUri), new DefaultAzureCredential()); } }) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); });
内容的提问来源于stack exchange,提问作者aggardner13
相关产品推荐
相关产品推荐

