【问题标题】:Identity 2.0 with custom tables带有自定义表的 Identity 2.0
【发布时间】:2014-08-17 04:31:00
【问题描述】:

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

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

当我使用 SQL Server 时,我想我会尝试在此链接上实现 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 指令或程序集引用?)

第二个错误是意料之中的,但是我不确定在这行代码中使用什么。有没有人在不使用实体框架的情况下实现自定义提供程序的经验?

谢谢。

更新 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”到“M​​icrosoft.AspNet.Identity.EntityFramework.IdentityUser”的隐式引用转换。

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

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 指令或程序集参考?)

【问题讨论】:

    标签: c# asp.net asp.net-mvc-5 asp.net-identity-2


    【解决方案1】:

    在您的示例中,您似乎想用其他东西替换 DbContext,但我相信实际上,您需要将精力集中在更高的层次上。

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

    在 2.0 框架中,身份存储的各个位被分解为几个接口。提供的默认实现UserStore&lt;IdentityUser&gt; 实现了其中几个接口,并使用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>
    

    由于您根本不想使用实体框架,因此您需要提供您自己的一些关键接口的实现,这些接口会将数据存储在您想要存储数据的位置。主界面为IUserStore&lt;Tuser,TKey&gt;。这定义了用于存储具有特定类型密钥的用户的合约。如果您只想存储用户而不存储其他信息,那么您可以实现此接口,然后将您的实现传递给UserManager,您应该可以开始了。

    这不太可能就足够了,尽管您可能需要为您的用户提供密码、角色、登录名等。如果是这样,那么您需要让实现IUserStore&lt;Tuser,TKey&gt; 的类也实现IUserPasswordStore&lt;TUser, TKey&gt;IRoleStore&lt;TRole, TKey&gt;IUserClaimStore&lt;TUser, TKey&gt;

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

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

    您可能还需要定义您自己的Identity* 类版本,这些版本存在于Entity framework already out of the box 中。因此,您将需要自己的 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)

    【讨论】:

    【解决方案2】:

    我自己对 Identity 还是很陌生。 您的 User 实体是否实现了 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
            );
        }   
    

    【讨论】:

      【解决方案3】:

      我认为最近在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);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-09-05
        • 1970-01-01
        • 2014-06-01
        • 2011-11-15
        • 2014-11-21
        • 2015-05-11
        相关资源
        最近更新 更多