如何解决.NET 8/9 Blazor Server应用Azure AD身份认证配置问题
你的核心问题是混淆了Blazor Server与Blazor WebAssembly的身份认证方案,误用了WebAssembly专属的组件和依赖包,以下是针对性的解决步骤:
一、修正Program.cs的认证配置
你当前的代码仅启用了认证框架,但未配置Azure AD的具体参数,且Blazor Server需要结合Cookie认证(保存用户身份)与OpenIdConnect(对接Azure AD)完成完整流程。修改后的代码如下:
using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authentication.OpenIdConnect; using Microsoft.Identity.Web; // 注册认证服务 builder.Services.AddAuthentication(options => { options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme; }) .AddCookie() .AddOpenIdConnect(options => { // 从配置文件读取Azure AD参数(建议用appsettings.json,避免硬编码) options.Authority = $"https://login.microsoftonline.com/{builder.Configuration["AzureAd:TenantId"]}/v2.0"; options.ClientId = builder.Configuration["AzureAd:ClientId"]; options.ClientSecret = builder.Configuration["AzureAd:ClientSecret"]; // 机密客户端需配置,公共客户端可省略 options.ResponseType = "code"; options.Scope.Add("openid"); options.Scope.Add("profile"); options.SaveTokens = true; options.GetClaimsFromUserInfoEndpoint = true; }); builder.Services.AddAuthorization(); // 中间件顺序不可颠倒 app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); // 添加登录/退出端点映射 app.MapGet("/login", async context => { await context.ChallengeAsync(OpenIdConnectDefaults.AuthenticationScheme, new AuthenticationProperties { RedirectUri = "/" // 登录成功后跳转主页 }); }); app.MapGet("/logout", async context => { await context.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); await context.SignOutAsync(OpenIdConnectDefaults.AuthenticationScheme, new AuthenticationProperties { RedirectUri = "/" // 退出成功后跳转主页 }); }); app.MapBlazorHub(); app.MapFallbackToPage("/_Host");
同时在appsettings.json中添加Azure AD配置项:
{ "AzureAd": { "TenantId": "你的租户ID", "ClientId": "你的客户端ID", "ClientSecret": "你的客户端密钥(机密客户端时填写)" } }
如果想简化配置,可以使用Microsoft.Identity.Web包,将上述AddOpenIdConnect部分替换为:
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"));
二、处理Pages/Authentication.razor文件
该文件是Blazor WebAssembly专属的认证路由组件,Blazor Server完全不需要,直接删除此文件即可。Blazor Server的登录/退出通过ASP.NET Core内置的认证端点触发,无需该组件。
三、重构Shared/LoginDisplay.razor
SignOutSessionStateManager是WebAssembly用于客户端会话管理的类,Blazor Server无需依赖。替换为Blazor Server适配的登录显示组件:
<AuthorizeView> <Authorized> 您好, @context.User.Identity.Name! <button class="btn btn-link" @onclick="SignOut">退出登录</button> </Authorized> <NotAuthorized> <button class="btn btn-link" @onclick="Login">登录</button> </NotAuthorized> </AuthorizeView> @code { [Inject] private NavigationManager NavigationManager { get; set; } = default!; private void Login() { // 跳转至登录端点,触发Azure AD认证流程 NavigationManager.NavigateTo("/login", forceLoad: true); } private void SignOut() { // 跳转至退出端点,清除身份Cookie并完成Azure AD登出 NavigationManager.NavigateTo("/logout", forceLoad: true); } }
四、清理错误依赖
不要安装Microsoft.AspNetCore.Components.WebAssembly.Authentication包,这是WebAssembly专属的。Blazor Server仅需Microsoft.AspNetCore.Authentication.OpenIdConnect和可选的Microsoft.Identity.Web包。
最后确认Azure AD应用配置:
- 重定向URI需设置为
https://localhost:xxxx/signin-oidc(xxxx为你的应用端口) - 机密客户端需生成并配置客户端密钥
- 权限需包含
openid、profile等必要项
内容的提问来源于stack exchange,提问作者Kempeth

