ASP.NET Core 标识的自定义 UserStore

mik*_*kes 5 .net asp.net asp.net-mvc entity-framework asp.net-core

基于在GitHub 上发布的实现,我制作了自己的UserStoreRoleStore,它们不使用实体框架(在附加到真实数据库之前,我目前只需要内存中的一个简单用户列表)。为了能够做到这一点,我不得不更改注册。我已经编写了自己的IdentityEntityFrameworkBuilderExtensions,没有 DbContext 和 TryAddSingleton 而不是 TryAddScoped,所以一旦初始化用户列表可以持续整个应用程序生命周期。问题是,Dispose 方法被调用了这么多次……我没有处理任何东西,但是调用的次数太多了。是不是因为我做了UserStoreRoleStore 单例,即使其他一切都按照它们的范围工作?

第二件事是,完成工作UserStore所需的最低限度是什么?

danludwig写道:你只需要IUserStoreIUserPasswordStore,这是非常有可能的,因为我做了一个店实现这两个接口和一个Rolestore的IRoleStore并seemd工作。由于在启动类中的一部分,我也做了RoleStoreservices.AddIdentity<ApplicationUser, IdentityRole>()。我为ASP.NET Core Web 应用程序使用了实体框架授权模板(带有个人用户帐户)。

Arve Systad 和 Anderson Matos写道,你需要这 8 个:

  1. IUserStore<TUser>
  2. IUserPasswordStore<TUser>
  3. IUserTwoFactorStore<TUser>
  4. IUserClaimStore<TUser>
  5. IRoleStore<TRole>
  6. IUserSecurityStampStore<TUser, string>
  7. IUserRoleStore<TUser, string>
  8. UserManager<TUser>

删除所有实体框架包后,我了解到它只提供了实现的UserStoreRoleStore(基于来自 GitHub 的源代码):

  1. IUserLoginStore,
  2. IUserRoleStore,
  3. IUserClaimStore,
  4. IUserPasswordStore,
  5. IUserSecurityStampStore,
  6. IUserEmailStore,
  7. IUserLockoutStore,
  8. IUserPhoneNumberStore,
  9. IQueryableUserStore,
  10. IUserTwoFactorStore,
  11. IUserAuthenticationTokenStore

和:

  1. IQueryableRoleStore,
  2. IRoleClaimStore

删除包后,我尝试为实体框架身份验证模板执行最小场景UserStoreRoleStore,我得到了:

  1. IQueryableUserStore,
  2. IUserPasswordStore,
  3. IUserSecurityStampStore,
  4. IUserLockoutStore,
  5. IUserTwoFactorStore,
  6. IUserRoleStore,
  7. IUserClaimStore

并且可能只有 IRoleStore,因为只有一个 Dispose 方法被调用。大多数接口在应用程序生命周期内仅提供 Get... 。添加用户时,我调用了一些 setter,但它们来自IQueryableUserStoreIUserPasswordStoreIUserSecurityStampStoreIUserLockoutStore。我真的需要所有这些接口吗?

编辑:

我当前的后 EF UserStore看起来像这样,只实现了提到的方法:

public class MyUserStore<TUser> :
    IQueryableUserStore<TUser>,
    IUserPasswordStore<TUser>,
    IUserSecurityStampStore<TUser>
    where TUser : MyIdentity
{
    private List<TUser> _identities = new List<TUser>();
    CreateAsync(...)
    FindByIdAsync(...)
    FindByNameAsync(...)
    GetPasswordHashAsync(...)
    GetSecurityStampAsync(...)
    GetUserIdAsync(...)
    GetUserNameAsync(...)
    SetNormalizedUserNameAsync(...)
    SetPasswordHashAsync(...)
    SetSecurityStampAsync(...)
}
Run Code Online (Sandbox Code Playgroud)

我想问的最后一件事是UserStore中 setter 方法的用途。他们主要在 Identity 中设置一些额外的属性:

    public async Task SetNormalizedUserNameAsync(TUser user, string normalizedName, CancellationToken cancellationToken)
    {
        cancellationToken.ThrowIfCancellationRequested();
        ThrowIfDisposed();
        if (user == null)
        {
            throw new ArgumentNullException("user");
        }
        user.NormalizedUserName = normalizedName;
        await UpdateAsync(user, cancellationToken);
    }
Run Code Online (Sandbox Code Playgroud)

为什么?这是某种数据库端验证的步骤吗?当您在添加新用户时检查应用程序经过的路径时,这有点奇怪,它从SetPasswordHashAsync开始并以CreateAsync结束...:P