ASP.NET Core Identity删除用户时如何同步删除关联声明?
在Blazor Server 8中删除用户时同步删除关联声明的实现方法
方法一:重写UserManager的删除逻辑
这种方法能让所有调用UserManager.DeleteAsync的地方自动同步删除声明,适合全局统一处理。
- 自定义UserManager类,继承自Identity的
UserManager<IdentityUser>,重写DeleteAsync方法:
public class CustomUserManager : UserManager<IdentityUser> { private readonly IUserClaimStore<IdentityUser> _claimStore; public CustomUserManager(IUserStore<IdentityUser> store, IOptions<IdentityOptions> optionsAccessor, IPasswordHasher<IdentityUser> passwordHasher, IEnumerable<IUserValidator<IdentityUser>> userValidators, IEnumerable<IPasswordValidator<IdentityUser>> passwordValidators, ILookupNormalizer keyNormalizer, IdentityErrorDescriber errors, IServiceProvider services, ILogger<UserManager<IdentityUser>> logger) : base(store, optionsAccessor, passwordHasher, userValidators, passwordValidators, keyNormalizer, errors, services, logger) { _claimStore = store as IUserClaimStore<IdentityUser> ?? throw new ArgumentNullException(nameof(_claimStore), "用户存储必须实现IUserClaimStore接口"); } public override async Task<IdentityResult> DeleteAsync(IdentityUser user) { // 先删除该用户的所有关联声明 var userClaims = await GetClaimsAsync(user); if (userClaims.Any()) { await RemoveClaimsAsync(user, userClaims); } // 执行默认的用户删除逻辑 return await base.DeleteAsync(user); } }
- 在Program.cs中替换默认的UserManager服务:
builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true) .AddEntityFrameworkStores<ApplicationDbContext>() .AddUserManager<CustomUserManager>(); // 注册自定义的UserManager
方法二:在删除账号页面手动处理
如果只需要在用户自行删除账号的页面处理,直接修改对应页面的逻辑即可:
假设你用的是Blazor组件版的删除账号页面,注入UserManager<IdentityUser>后,在删除方法中先删声明再删用户:
[Inject] private UserManager<IdentityUser> UserManager { get; set; } [Inject] private AuthenticationStateProvider AuthStateProvider { get; set; } [Inject] private SignOutManager<IdentityUser> SignOutManager { get; set; } [Inject] private NavigationManager NavManager { get; set; } private async Task DeleteMyAccount() { var authState = await AuthStateProvider.GetAuthenticationStateAsync(); var currentUser = await UserManager.FindByNameAsync(authState.User.Identity!.Name!); if (currentUser == null) return; // 删除当前用户的所有声明 var userClaims = await UserManager.GetClaimsAsync(currentUser); if (userClaims.Any()) { await UserManager.RemoveClaimsAsync(currentUser, userClaims); } // 删除用户账号 var deleteResult = await UserManager.DeleteAsync(currentUser); if (deleteResult.Succeeded) { await SignOutManager.SignOutAsync(); NavManager.NavigateTo("/"); } else { // 这里可以添加错误提示逻辑,比如遍历deleteResult.Errors展示错误信息 } }
如果是Identity自带的Razor页面(Pages/Account/DeleteAccount.cshtml.cs),则在OnPostAsync方法中添加相同的声明删除逻辑即可。
验证
完成后,删除用户后检查数据库的AspNetUserClaims表,确认该用户的所有记录已被清除。
内容的提问来源于stack exchange,提问作者David Thielen
相关产品推荐
相关产品推荐

