在 ASP.NET 5 中使用自定义用户存储和角色存储



我已经为我的项目实现了自定义角色存储和自定义用户存储,该项目使用 ASP.NET 5、MVC 6、EF 7 和标识 3。但是 - 我不太清楚如何配置身份以使用我的自定义角色存储和自定义用户存储而不是通常的产品。如何重新配置系统以使用我的自定义类?

PS:我也有自定义的用户和角色类。

溶液

这是我最终所做的。首先,我从项目中卸载了"标识实体框架"包。这导致缺少一些东西,所以我重新实现了它们(阅读:从这里复制了它们),并将它们放在"标准"命名空间中以表明它们尚未自定义。我现在有一个包含以下内容的"安全"命名空间:

  • 标准
    • 身份角色.cs
    • IdentityRoleClaim.cs
    • 身份用户.cs
    • 身份用户声明.cs
    • 身份用户登录.cs
    • 身份用户角色.cs
  • 生成器扩展.cs
  • IdentityDbContext.cs
  • Resources.resx
  • 角色.cs
  • 角色存储.cs
  • 用户.cs
  • 用户存储.cs

以粗体显示的项目包含项目特定的功能。

允许我使用自定义存储的代码位于"BuilderExtensions"文件中,该文件包含以下类:

public static class BuilderExtensions
{
    public static IdentityBuilder AddCustomStores<TContext, TKey>(this IdentityBuilder builder)
        where TContext : DbContext
        where TKey : IEquatable<TKey>
    {
        builder.Services.TryAdd(GetDefaultServices(builder.UserType, builder.RoleType, typeof(TContext), typeof(TKey)));
        return builder;
    }
    private static IServiceCollection GetDefaultServices(Type userType, Type roleType, Type contextType, Type keyType)
    {
        var userStoreType = typeof(UserStore<,,,>).MakeGenericType(userType, roleType, contextType, keyType);
        var roleStoreType = typeof(RoleStore<,,>).MakeGenericType(roleType, contextType, keyType);
        var services = new ServiceCollection();
        services.AddScoped(
            typeof(IUserStore<>).MakeGenericType(userType),
            userStoreType);
        services.AddScoped(
            typeof(IRoleStore<>).MakeGenericType(roleType),
            roleStoreType);
        return services;
    }
}

然后,这允许我在 Startup.cs 文件中编写以下内容:

services.AddIdentity<User, Role>()
    .AddCustomStores<PrimaryContext, string>()
    .AddDefaultTokenProviders();

并且将使用自定义商店。请注意,PrimaryContext 是我的整个项目 DbContext 的名称。它继承自 IdentityDbContext。

讨论

我本可以保留"标识实体框架"包,并避免复制"标准"命名空间的内容,但我选择不这样做,以便我可以保持标识符简短明确。

查看此部分在用于 ASP.NET 标识的自定义存储提供程序概述中重新配置应用程序以使用新的存储提供程序

具体而言,"如果项目中包含默认存储提供程序,则必须删除默认提供程序并将其替换为提供程序。

public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context) 
{
    var manager = new ApplicationUserManager(new YourNewUserStore(context.Get<ExampleStorageContext>()));
    ...
}

最新更新