如何在Azure App Service的Blazor Server中获取Easy Auth认证用户及角色?
解决Azure App Service上Blazor Server(.NET 6)通过Easy Auth获取当前用户及角色的问题
Blazor Server和WebAssembly的Easy Auth处理逻辑存在差异,由于Blazor Server运行在服务器端,需要手动将App Service注入的Easy Auth请求头转换为.NET的ClaimsPrincipal。以下是具体解决步骤:
1. 在Program.cs中添加认证中间件
虽然Easy Auth接管了认证流程,但仍需在应用中配置基础认证服务,用于解析App Service传递的用户头信息:
var builder = WebApplication.CreateBuilder(args); builder.Services.AddRazorPages(); builder.Services.AddServerSideBlazor(); // 配置Cookie认证,解析Easy Auth传递的用户数据 builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie(options => { options.Events = new CookieAuthenticationEvents { OnValidatePrincipal = context => { var request = context.HttpContext.Request; // 读取Easy Auth注入的Base64编码用户信息 var userBase64 = request.Headers["X-MS-CLIENT-PRINCIPAL"].FirstOrDefault(); if (string.IsNullOrEmpty(userBase64)) { return Task.CompletedTask; } // 解码用户信息 var userBytes = Convert.FromBase64String(userBase64); var userJson = Encoding.UTF8.GetString(userBytes); var easyAuthUser = JsonSerializer.Deserialize<EasyAuthUser>(userJson); // 构建Claims集合 var claims = new List<Claim> { new(ClaimTypes.NameIdentifier, easyAuthUser.UserId), new(ClaimTypes.Name, easyAuthUser.UserName), new(ClaimTypes.Email, easyAuthUser.Email) }; // 读取并解码角色信息 var rolesBase64 = request.Headers["X-MS-CLIENT-PRINCIPAL-ROLES"].FirstOrDefault(); if (!string.IsNullOrEmpty(rolesBase64)) { var rolesBytes = Convert.FromBase64String(rolesBase64); var rolesJson = Encoding.UTF8.GetString(rolesBytes); var roles = JsonSerializer.Deserialize<List<string>>(rolesJson); claims.AddRange(roles.Select(r => new Claim(ClaimTypes.Role, r))); } // 更新当前用户的身份信息 var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme); context.Principal = new ClaimsPrincipal(identity); return Task.CompletedTask; } }; }); builder.Services.AddAuthorization(); var app = builder.Build(); // 中间件顺序必须严格遵循:认证→授权→路由 app.UseAuthentication(); app.UseAuthorization(); if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.MapBlazorHub(); app.MapFallbackToPage("/_Host"); app.Run(); // 用于解析Easy Auth用户信息的模型类 public class EasyAuthUser { public string UserId { get; set; } = string.Empty; public string UserName { get; set; } = string.Empty; public string Email { get; set; } = string.Empty; }
2. 在Blazor组件中获取用户及角色
完成上述配置后,可通过AuthenticationStateProvider在组件中直接获取认证用户信息:
@page "/" @inject AuthenticationStateProvider AuthStateProvider <h1>欢迎, @currentUser?.Identity?.Name!</h1> @if (currentUser?.Identity?.IsAuthenticated == true) { <div> <p>你的角色:</p> <ul> @foreach (var role in currentUser.Claims.Where(c => c.Type == ClaimTypes.Role)) { <li>@role.Value</li> } </ul> </div> } else { <p>你尚未登录。</p> } @code { private ClaimsPrincipal? currentUser; protected override async Task OnInitializedAsync() { var authState = await AuthStateProvider.GetAuthenticationStateAsync(); currentUser = authState.User; } }
3. 验证App Service配置
确保App Service和Azure AD配置无误:
- 在App Service的「Authentication/Authorization」面板中,已启用Azure AD作为身份提供商,且「未认证请求的处理动作」设置为「使用Azure Active Directory登录」。
- 在Azure AD应用注册中,已配置所需应用角色,并将目标用户/组分配到对应角色。
- 确认App Service的「允许的外部重定向URL」包含应用完整地址(例如
https://<你的应用名>.azurewebsites.net)。
4. 额外注意事项
- Blazor Server依赖SignalR,确保Easy Auth能正确处理SignalR协商请求:已登录用户的SignalR连接会自动携带认证信息,未登录用户会被重定向到AAD登录页。
- 中间件顺序至关重要,
UseAuthentication()必须在UseRouting()之前,UseAuthorization()紧随其后,否则认证信息无法被正确读取。
内容的提问来源于stack exchange,提问作者LongNeckTimmy
相关产品推荐
相关产品推荐

