首页 文章

带有自定义表的Identity 2.0

提问于
浏览
29

我是ASP.NET身份的新手,我仍然试图了解它是如何工作的 . 不幸的是,我发现我尝试过的许多教程都是针对Identity 1.0的,而我正在尝试使用Identity 2.0 .

我面临的最大问题是我认为很简单,但事实证明并非如此 . 我要做的是使用现有数据库和现有用户表 . 目前我所能做的就是让Identity创建自己的表来存储用户数据 . 我不想使用Entity Framework,但是我很难将Entity Framework与Identity 2.0分开 .

虽然我的情况是'm using SQL Server, I thought I' d尝试在此链接上实现MySQL的自定义提供程序:http://www.asp.net/identity/overview/extensibility/implementing-a-custom-mysql-aspnet-identity-storage-providerhttps://github.com/raquelsa/AspNet.Identity.MySQL . 这似乎只在身份1下工作 . 似乎有一个较新的,但使用实体框架 . 我也试过https://github.com/ILMServices/RavenDB.AspNet.Identity .

有了我尝试过的所有东西,我会遇到以下问题:

var manager = new IdentityUserManager(new UserStore<IdentityUser>(context.Get<ApplicationDbContext>()));

我面临的问题是我需要根据RavenDB的说明删除ApplicaitonDbContext类,但是我不知道该放入什么内容 .

我得到的错误是:

非泛型类型'AspNet.Identity.MySQL.UserStore'不能与类型参数一起使用

找不到类型或命名空间名称'ApplicationDbContext'(您是否缺少using指令或程序集引用?)

第二个错误是预期的,但是我不确定在这行代码中使用什么 . 有没有人在没有使用Entity Framework的情况下实现自定义提供程序的经验?

谢谢 .

Update 1:

我已经尝试了以下教程[http://aspnetguru.com/customize-authentication-to-your-own-set-of-tables-in-asp-net-mvc-5/],但它似乎是不完整的,在完全遵循教程时出现编译或运行时错误 . 我还有一些问题......

将“ApplicationUser”的所有实例替换为“User”时,IdentityConfig.cs中的以下行出现问题

var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<MyDbContext>()));

将ApplicationUser更改为User会产生以下错误

类型'WebApplicationTest2.Models.User'不能在泛型类型或方法'Microsoft.AspNet.Identity.EntityFramework.UserStore'中用作类型参数'TUser' . 没有从“WebApplicationTest2.Models.User”到“Microsoft.AspNet.Identity.EntityFramework.IdentityUser”的隐式引用转换 .

我也很难弄清楚如何使用用户管理器和许多ASync方法 . 以下行不起作用:

AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, await user.GenerateUserIdentityAsync(UserManager));

在AccountController.cs中,出现以下错误:

'Microsoft.Owin.Security.IAuthenticationManager.SignIn(Microsoft.Owin.Security.AuthenticationProperties,params System.Security.Claims.ClaimsIdentity [])'的最佳重载方法匹配具有一些无效参数 . 'WebApplicationTest2.Models.User'不包含'GenerateUserIdentityAsync'的定义,并且没有可以找到接受类型'WebApplicationTest2.Models.User'的第一个参数的扩展方法'GenerateUserIdentityAsync'(您是否缺少using指令或程序集引用?)

3 回答

  • 1

    在您的示例中,您似乎想要用其他东西替换 DbContext ,但我相信实际上,您需要将您的努力集中在一个更高的级别 .

    该框架有一个类 UserManager ,负责管理但不存储用户及其相关信息 . 当它想要存储用户(或其相关信息)时,默认是使用提供的 UserStore<IdentityUser> ,它知道如何使用 DbContext 在数据库中存储 IdentityUser 实例 .

    在2.0框架中,身份存储的各个位被分成几个接口 . 提供的默认实现, UserStore<IdentityUser> 实现了其中几个接口,并使用 DBContext 将数据全部存储在数据库中 .

    如果你看一下基于UserStore的默认提供的实体框架的定义,你可以看到它实现了许多这些小接口:

    public class UserStore<TUser, TRole, TKey, TUserLogin, TUserRole, TUserClaim> : IUserLoginStore<TUser, TKey>, 
    IUserClaimStore<TUser, TKey>, IUserRoleStore<TUser, TKey>, IUserPasswordStore<TUser, TKey>, 
    IUserSecurityStampStore<TUser, TKey>, IQueryableUserStore<TUser, TKey>, IUserEmailStore<TUser, TKey>, 
    IUserPhoneNumberStore<TUser, TKey>, IUserTwoFactorStore<TUser, TKey>, IUserLockoutStore<TUser, TKey>, 
    IUserStore<TUser, TKey>, IDisposable 
    where TUser : IdentityUser<TKey, TUserLogin, TUserRole, TUserClaim>
    where TRole : IdentityRole<TKey, TUserRole>
    where TKey : Object, IEquatable<TKey>
    where TUserLogin : new(), IdentityUserLogin<TKey>
    where TUserRole : new(), IdentityUserRole<TKey>
    where TUserClaim : new(), IdentityUserClaim<TKey>
    

    由于您根本不想使用Entity Framework,因此您需要提供自己的一些关键接口实现,这些接口将把数据存储在您希望存储数据的位置 . 主界面是IUserStore<Tuser,TKey> . 这定义了用于存储具有特定类型的密钥的用户的 Contract . 如果您只想存储用户而没有其他信息,那么您可以实现此接口,然后将您的实现传递给 UserManager ,您应该好好去 .

    这不太可能虽然您可能希望为用户提供密码,角色,登录等,但这已经足够了 . 如果是这样,那么你需要让实现 IUserStore<Tuser,TKey> 的类也实现 IUserPasswordStore<TUser, TKey>IRoleStore<TRole, TKey>IUserClaimStore<TUser, TKey> .

    你可以找到所有接口的列表on MSDN here

    根据您要使用的位,您需要实现这些接口 .

    您可能还需要为Entity framework already out of the box定义自己的 Identity* 类版本 . 所以你需要你自己的 IdentityUser 类代表你想要存储的用户, IdentityUserClaim 代表用户声明 . 我还没有确定,但我的感觉是你必须这样做 .

    Scott Allen对模型的各个部分有一个good article可能有用 .

    至于你对这一行的问题:

    AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, await user.GenerateUserIdentityAsync(UserManager));
    

    有一个名为 GenerateUserIdentityAsync 的方法,它在 Applicationuser 上定义,扩展 IdentityUser . 它在我相信的模板项目中定义,看起来像这样:

    public class ApplicationUser : IdentityUser 
    {    
    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(
        UserManager<ApplicationUser> manager) {
        // Note the authenticationType must match the one 
        // defined in CookieAuthenticationOptions.AuthenticationType
        var userIdentity = 
            await manager.CreateIdentityAsync(this, 
                DefaultAuthenticationTypes.ApplicationCookie);
        // Add custom user claims here
        return userIdentity;
        }
    }
    

    由于您不再使用实体框架 IdentityUser ,您需要定义类似的方法或您自己的 User 类或以其他方式实现相同的功能(例如只需调用 await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie)

  • 1

    我自己对身份很陌生 . 您的用户实体是否实现了IUser接口?例如

    public partial class User : IUser<Guid> //Whatever your key is
    {
        public Task<ClaimsIdentity> GenerateUserIdentityAsync(ApplicationUserManager manager)
        {
            return Task.FromResult(GenerateUserIdentity(manager));
        }
    
        public ClaimsIdentity GenerateUserIdentity(ApplicationUserManager manager)
        {
            // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
            var userIdentity = manager.CreateIdentity<User, Guid>(this, DefaultAuthenticationTypes.ApplicationCookie);
            // Add custom user claims here
            return userIdentity;
        }
    }
    

    然后登录你可以打电话给上面:

    public async Task SignInAsync(User user, bool isPersistent)
        {
            var userIdentity = await user.GenerateUserIdentityAsync(UserManager);
            AuthenticationManager.SignIn(
                new AuthenticationProperties
                {
                    IsPersistent = isPersistent
                },
                userIdentity
            );
        }
    
  • 37

    我认为最近在 ApplicationUser 中对此进行了更新:

    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager, string authenticationType)
    {
        // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
        var userIdentity = await manager.CreateIdentityAsync(this, authenticationType);
        // Add custom user claims here
        return userIdentity;
    }
    

    它被称为 AccountController - > GetExternalLogin

    ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(UserManager,
        OAuthDefaults.AuthenticationType);
    ClaimsIdentity cookieIdentity = await user.GenerateUserIdentityAsync(UserManager,
        CookieAuthenticationDefaults.AuthenticationType);
    

相关问题