如何让部署的Blazor Web应用以当前用户身份连接Azure SQL Server?
我搭建了基于.NET 8.0的Blazor Web应用,连接Azure SQL Server数据库。应用已在Azure注册并配置好ClientID、TenantID及密钥,服务器公网IP也已加入Azure SQL Server白名单。本地运行一切正常,但发布到IIS服务器后,授权功能正常却无法连接数据库,IIS已启用Windows认证。
Program.cs 代码
using HiSS.Body.Components; using HiSS.DB; using HiSS.Shared.DBAccess; using HiSS.Shared.Helpers; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc.Authorization; using Microsoft.Identity.Web; using Microsoft.Identity.Web.UI; var builder = WebApplication.CreateBuilder(args); // EntraId 认证 // builder.Services.AddMicrosoftIdentityWebAppAuthentication(builder.Configuration); builder.Services.AddControllersWithViews(options => { var policy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build(); options.Filters.Add(new AuthorizeFilter(policy)); }).AddMicrosoftIdentityUI(); builder.Services.AddAuthenticationCore(); builder.Services.AddHttpContextAccessor(); builder.Services.AddMemoryCache(); // 辅助服务 // builder.Services.AddSingleton<IDBAccess, DataAccessService>(); builder.Services.AddSingleton<AppSettingsHelper>(); builder.Services.AddSingleton(sp => { // 从配置加载Azure AD凭据 var clientId = builder.Configuration["AzureAd:ClientId"]; var tenantId = builder.Configuration["AzureAd:TenantId"]; var clientSecret = builder.Configuration["AzureAd:ClientSecret"]; // 确保Azure AD通信使用HTTPS设置 return new EntraIDHelper(clientId!, tenantId!, clientSecret!); }); // 向容器添加服务 // builder.Services.AddRazorComponents() .AddInteractiveServerComponents(); // Bootstrap 库 // builder.Services.AddBlazorBootstrap(); // Telerik 组件 // builder.Services.AddTelerikBlazor(); var app = builder.Build(); // 配置HTTP请求管道 if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Error", createScopeForErrors: true); // 默认HSTS值为30天,生产环境可按需修改 app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseAntiforgery(); app.MapControllers(); app.UseAuthentication(); app.UseAuthorization(); app.MapRazorComponents<App>() .AddInteractiveServerRenderMode(); app.Run();
appsettings.json 配置
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "AzureAd": { "Instance": "https://login.microsoftonline.com/", "TenantId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "ClientId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "ServicePrincipleObjectId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "ClientSecret": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "Domain": "customDomain.onmicrosoft.com", "CallbackPath": "/signin-oidc" }, "DbConfig": { "DatabaseName": "<dbname>", "ServerName": "<servername>.database.windows.net" }, "AllowedHosts": "*" }
数据库连接字符串
"Server=tcp:{_server},1433;Database={_database};Authentication=Active Directory Default;"
更新1:修改认证逻辑后的错误
我移除了连接字符串中的Authentication设置,在SQL连接代码中添加了获取token的逻辑,本地运行正常,但服务器仍无法连接。调试时获取token出现以下错误:
Azure.Identity.CredentialUnavailableException HResult=0x80131500
Message=DefaultAzureCredential无法从包含的凭据中检索token。
- EnvironmentCredential认证不可用,环境变量未完全配置。
- WorkloadIdentityCredential认证不可用,工作负载选项未完全配置。
- ManagedIdentityCredential认证不可用,未收到托管身份端点的响应。
- 无法访问Visual Studio Token provider,路径为C:\Windows\system32\config\systemprofile\AppData\Local.IdentityService\AzureServiceAuth\tokenprovider.json
- 未安装Azure CLI
- 未安装Az.Accounts模块(版本需>=2.2.0)
- 未找到Azure Developer CLI
源=Azure.Identity 堆栈跟踪: at
Azure.Identity.DefaultAzureCredential.d__14.MoveNext()
at System.Threading.Tasks.ValueTask1.get_Result() at System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable1.ConfiguredValueTaskAwaiter.GetResult()
at
Azure.Identity.DefaultAzureCredential.d__12.MoveNext()
at Azure.Identity.CredentialDiagnosticScope.FailWrapAndThrow(Exception
ex, String additionalMessage, Boolean isCredentialUnavailable) at
Azure.Identity.DefaultAzureCredential.d__12.MoveNext()
at System.Threading.Tasks.ValueTask1.get_Result() at System.Runtime.CompilerServices.ValueTaskAwaiter1.GetResult() at
Azure.Core.Pipeline.TaskExtensions.EnsureCompleted[T](ValueTask`1
task) at
Azure.Identity.DefaultAzureCredential.GetToken(TokenRequestContext
requestContext, CancellationToken cancellationToken) at
HiSS.DB.DataAccessService.RunSP(String procedure, SqlParameter[]
paramlist, Object retObject) in
C:\Dev\HiSS\HiSS.DB\DataAccessService.cs:line 337此异常最初在此调用堆栈中引发:
[外部代码]内部异常1: AggregateException: 尝试认证时遇到多个异常。(EnvironmentCredential认证不可用,环境变量未完全配置。)(WorkloadIdentityCredential认证不可用,工作负载选项未完全配置。)(ManagedIdentityCredential认证不可用,未收到托管身份端点的响应。)(无法访问Visual Studio Token provider,路径为C:\Windows\system32\config\systemprofile\AppData\Local.IdentityService\AzureServiceAuth\tokenprovider.json)(未安装Azure CLI)(未安装Az.Accounts模块(版本需>=2.2.0))(未找到Azure Developer CLI。)
内部异常2: CredentialUnavailableException: EnvironmentCredential认证不可用,环境变量未完全配置。
更新2:当前问题
最终通过在IIS服务器级设置环境变量实现了数据库连接,但站点级设置会在每次发布时被覆盖。现在的问题是:连接数据库时使用的身份是十六进制代码而非用户登录名,导致数据库权限验证失败,即使已经创建了外部提供者用户也无法解决。
内容的提问来源于stack exchange,提问作者Rob Marsh

