.NET 7迁移至.NET 8 Blazor Server权限异常:直接访问URL报403
问题原因
直接输入URL访问Admin页面时,请求走ASP.NET Core服务器端管道并触发预渲染,此时ASP.NET Core授权系统会直接使用HttpContext.User做权限检查。但你当前仅在Blazor的CustomAuthenticationStateProvider中添加角色,该逻辑只在Blazor组件生命周期内生效,服务器端管道的HttpContext.User并没有这些角色,因此授权失败返回403。而点击页面链接属于客户端导航,完全由Blazor路由处理,会使用CustomAuthenticationStateProvider提供的带角色的用户信息,所以授权正常。
解决方案
1. 完善ASP.NET Core请求管道
在Program.cs的请求管道配置中,添加认证和授权中间件,顺序必须放在UseAntiforgery之前:
app.UseHttpsRedirection(); app.UseStaticFiles(); // 添加认证、授权中间件,顺序不可调换 app.UseAuthentication(); app.UseAuthorization(); app.UseAntiforgery();
2. 在服务器端统一添加角色
改用IClaimsTransformation接口,在服务器端认证完成后直接给用户添加角色,确保HttpContext.User在任何场景下都包含所需角色:
创建ClaimsTransformer类:
public class ClaimsTransformer : IClaimsTransformation { public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal) { var identity = principal.Identity as ClaimsIdentity; // 为用户添加角色声明 identity.AddClaim(new Claim(ClaimTypes.Role, "Admin")); identity.AddClaim(new Claim(ClaimTypes.Role, "Manager")); return Task.FromResult(principal); } }
在Program.cs中注册该服务:
builder.Services.AddScoped<IClaimsTransformation, ClaimsTransformer>();
3. 简化自定义AuthenticationStateProvider(可选)
现在HttpContext.User已包含完整角色信息,CustomAuthenticationStateProvider可简化为直接返回上下文用户:
public class CustomAuthenticationStateProvider : AuthenticationStateProvider { private readonly IHttpContextAccessor _httpContextAccessor; public CustomAuthenticationStateProvider(IHttpContextAccessor httpContextAccessor) { _httpContextAccessor = httpContextAccessor; } public override Task<AuthenticationState> GetAuthenticationStateAsync() { var user = _httpContextAccessor.HttpContext.User; return Task.FromResult(new AuthenticationState(user)); } }
完成以上修改后,无论直接输入URL还是点击页面链接,用户都会携带正确的角色信息,授权检查均可正常通过。
内容的提问来源于stack exchange,提问作者Peter Forsbom
相关产品推荐
相关产品推荐

