Blazor自定义授权状态刷新后失效问题求助
Blazor自定义AuthenticationStateProvider刷新后认证状态丢失问题解决方案
问题根源分析
- 拼写错误:自定义认证状态提供者类名、方法名中的
Authentitaction应为Authentication,可能导致认证状态通知或依赖注入逻辑异常。 - ClaimsIdentity配置缺失:
UpdateAuthenticationState方法中创建ClaimsIdentity时未指定认证类型,导致用户身份的IsAuthenticated属性可能为false,即使SessionStorage中存在用户数据。 - 认证状态传递缺失:组件未被
CascadingAuthenticationState包裹,无法正确获取刷新后的认证状态。 - 空引用未防护:业务逻辑未对
LoggedUserCode为空的情况做判断,直接访问FirstOrDefault返回的null对象属性,引发空引用异常导致Dapper操作崩溃。
解决方案步骤
1. 修正自定义认证状态提供者的拼写与配置
将类名、方法名的拼写错误修正,并确保ClaimsIdentity统一指定认证类型:
using Microsoft.AspNetCore.Components.Authorization; using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage; using System.Security.Claims; using System.Collections.Generic; namespace VikkingWebApp.Authentication { // 修正类名拼写 public class CustomAuthenticationStateProvider : AuthenticationStateProvider { private readonly ProtectedSessionStorage _sessionStorage; private ClaimsPrincipal _anonymous = new ClaimsPrincipal(new ClaimsIdentity()); public CustomAuthenticationStateProvider(ProtectedSessionStorage sessionStorage) { _sessionStorage = sessionStorage; } public override async Task<AuthenticationState> GetAuthenticationStateAsync() { try { var userSessionStorageResult = await _sessionStorage.GetAsync<UserSession>("UserSession"); var userSession = userSessionStorageResult.Success ? userSessionStorageResult.Value : null; if (userSession == null) return new AuthenticationState(_anonymous); var claimsPrincipal = new ClaimsPrincipal(new ClaimsIdentity(new List<Claim> { new Claim(ClaimTypes.Name, userSession.UserCode), new Claim(ClaimTypes.Role, userSession.Role) }, "CustomAuth")); return new AuthenticationState(claimsPrincipal); } catch { return new AuthenticationState(_anonymous); } } // 修正方法名拼写,并添加认证类型 public async Task UpdateAuthenticationState(UserSession userSession) { ClaimsPrincipal claimsPrincipal; if (userSession != null) { await _sessionStorage.SetAsync("UserSession", userSession); claimsPrincipal = new ClaimsPrincipal(new ClaimsIdentity(new List<Claim> { new Claim(ClaimTypes.Name, userSession.UserCode), new Claim(ClaimTypes.Role, userSession.Role) }, "CustomAuth")); // 统一认证类型,确保IsAuthenticated为true } else { await _sessionStorage.DeleteAsync("UserSession"); claimsPrincipal = _anonymous; } NotifyAuthenticationStateChanged(Task.FromResult(new AuthenticationState(claimsPrincipal))); } } }
同时更新Program.cs中的服务注册:
builder.Services.AddScoped<ProtectedSessionStorage>(); builder.Services.AddScoped<AuthenticationStateProvider, CustomAuthenticationStateProvider>();
2. 确保全局传递认证状态
在App.razor中用CascadingAuthenticationState包裹路由组件,让所有子组件能获取到认证状态:
<CascadingAuthenticationState> <Router AppAssembly="@typeof(App).Assembly"> <Found Context="routeData"> <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" /> <FocusOnNavigate RouteData="@routeData" Selector="h1" /> </Found> <NotFound> <PageTitle>Not found</PageTitle> <LayoutView Layout="@typeof(MainLayout)"> <p role="alert">Sorry, there's nothing at this address.</p> </LayoutView> </NotFound> </Router> </CascadingAuthenticationState>
3. 修正组件中认证状态的获取逻辑
在组件中通过CascadingParameter注入认证状态任务,并完善空值防护:
using Microsoft.AspNetCore.Components.Authorization; // 组件中添加CascadingParameter [CascadingParameter] private Task<AuthenticationState> AuthenticationStateTask { get; set; } private string LoggedUserCode { get; set; } private User user1 = new User(); // 替换为你的实体类 private async Task LogUsername() { var authState = await AuthenticationStateTask; var user = authState.User; LoggedUserCode = user.Identity.IsAuthenticated ? user.Identity.Name : null; } protected override async Task OnInitializedAsync() { await LogUsername(); // 多层空值防护,避免空引用 if (!string.IsNullOrEmpty(LoggedUserCode)) { var matchedUser = Authentication.UserAccountService._users.FirstOrDefault(x => x.Kod == LoggedUserCode); if (matchedUser != null) { user1.Id = matchedUser.Id; // 移除不必要的Task.Run,Blazor异步方法无需额外包装 element = await adminPanels.GetUser(user1.Id); mg = await wS.GetWarehouse(element.magazyn); // okuciaObj = await VikkingOkucia.PobierzOkucia(mg.id); } } _table?.SetEditingItem(null); }
4. 业务逻辑空值防护
确保所有依赖用户身份的操作都先检查用户是否已认证、数据是否存在,避免空引用异常导致Dapper操作崩溃。
内容的提问来源于stack exchange,提问作者Przemo
相关产品推荐
相关产品推荐

