Blazor WebAssembly迁移身份验证授权模板代码失败
Blazor WebAssembly 身份验证迁移故障排查
我将Visual Studio最新更新的Identity模板中的身份验证与授权代码迁移到自己的Blazor WebAssembly(客户端-服务器)Web应用后出现错误,以下是已执行的操作及问题:
AccountController.cs(已调试,无问题)
[HttpPost] [Route("/api/account/login")] public async Task<SignInResult> Login([FromBody] LoginModel model) { var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, false); return result; }
PersistingServerAuthenticationStateProvider.cs(登录时完全未进入此类,是否正常?)
internal sealed class PersistingServerAuthenticationStateProvider : ServerAuthenticationStateProvider, IDisposable { private readonly PersistentComponentState state; private readonly IdentityOptions options; private readonly PersistingComponentStateSubscription subscription; private Task<AuthenticationState>? authenticationStateTask; public PersistingServerAuthenticationStateProvider( PersistentComponentState persistentComponentState, IOptions<IdentityOptions> optionsAccessor) { state = persistentComponentState; options = optionsAccessor.Value; AuthenticationStateChanged += OnAuthenticationStateChanged; subscription = state.RegisterOnPersisting(OnPersistingAsync, RenderMode.InteractiveWebAssembly); } private void OnAuthenticationStateChanged(Task<AuthenticationState> task) { authenticationStateTask = task; } private async Task OnPersistingAsync() { if (authenticationStateTask is null) { throw new UnreachableException($"Authentication state not set in {nameof(OnPersistingAsync)}()."); } var authenticationState = await authenticationStateTask; var principal = authenticationState.User; if (principal.Identity?.IsAuthenticated == true) { var userId = principal.FindFirst(options.ClaimsIdentity.UserIdClaimType)?.Value; var email = principal.FindFirst(options.ClaimsIdentity.EmailClaimType)?.Value; if (userId != null && email != null) { state.PersistAsJson(nameof(UserInfo), new UserInfo { UserId = userId, Email = email, }); } } } public void Dispose() { subscription.Dispose(); AuthenticationStateChanged -= OnAuthenticationStateChanged; } }
PersistentAuthenticationStateProvider(验证时始终返回空值,访问授权页面未进入此类方法)
构造函数中始终进入return分支,导致认证状态始终为未认证:
public class PersistentAuthenticationStateProvider : AuthenticationStateProvider { private static readonly Task<AuthenticationState> defaultUnauthenticatedTask = Task.FromResult(new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity()))); private readonly Task<AuthenticationState> authenticationStateTask = defaultUnauthenticatedTask; public PersistentAuthenticationStateProvider(PersistentComponentState state) { if (!state.TryTakeFromJson<UserInfo>(nameof(UserInfo), out var userInfo) || userInfo is null) { return; // 始终进入此处 } Claim[] claims = [ new Claim(ClaimTypes.NameIdentifier, userInfo.UserId), new Claim(ClaimTypes.Name, userInfo.Email), new Claim(ClaimTypes.Email, userInfo.Email) ]; authenticationStateTask = Task.FromResult( new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity(claims, authenticationType: nameof(PersistentAuthenticationStateProvider))))); } public override Task<AuthenticationState> GetAuthenticationStateAsync() => authenticationStateTask; }
注册配置
- 服务器端Program.cs已注册
PersistingServerAuthenticationStateProvider - 客户端Program.cs已注册
PersistentAuthenticationStateProvider
与模板项目的核心差异:我的项目中Login.razor视图位于客户端,而模板生成的视图位于服务器端。
目前核心问题:PersistingServerAuthenticationStateProvider完全无法触发调试断点,怀疑遗漏了关键配置步骤。
客户端注册代码
builder.Services.AddAuthorizationCore(); builder.Services.AddCascadingAuthenticationState(); builder.Services.AddSingleton<AuthenticationStateProvider, PersistentAuthenticationStateProvider>();
服务器端注册代码
builder.Services.AddDbContext<IdentityDataContext>((options) => { options.UseSqlServer(databaseConfig?.ConnectionString); }); builder.Services.AddIdentityCore<User>()//options => options.SignIn.RequireConfirmedAccount = true .AddEntityFrameworkStores<IdentityDataContext>() .AddSignInManager() .AddDefaultTokenProviders(); builder.Services.AddScoped<UserManager<User>>(); builder.Services.AddScoped<AuthenticationStateProvider, PersistingServerAuthenticationStateProvider>();
内容的提问来源于stack exchange,提问作者user571203
相关产品推荐
相关产品推荐

