c# - 如何为新的 Microsoft.Asp.NET Identity (MVC5) 设置自定义架构

标签 c# asp.net asp.net-mvc asp.net-identity

我一直在为 Microsoft 引入的 One Asp.Net 实现引入的新 Forms Identity 流程而苦苦挣扎——尤其是在 Asp.NET MVC5 方面。

我的问题有两个:

  1. 如何将上下文指向常规 SQL 实例而不是 LocalDb。至少 LocalDb 对我来说不可行,因为我的托管服务提供商不支持它。

  2. 如何为我的身份实体使用自定义数据库。

我意识到我可以更改 Web.Config 中“DefaultConnection”条目的连接字符串。但这仍然给我留下一系列以“AspNet”或类似前缀为前缀的表格。

在旧的 MembershipProvider 架构下,您可以继承提供者并以任何您想要的方式实现您需要的一切,方法是在 Web.config 中放置条目,将表单例份验证过程指向您的自定义成员资格过程。

但是,对于新的身份进程,web.config 中没有 Hook 可供使用。此外,从它继承没有任何好处,因为似乎没有任何东西是虚拟的,最重要的是,它是从现有上下文继承来启动的。

由于这是 Microsoft 的新创意,因此没有关于如何自定义新流程的真正演练,只是展示新流程有多棒的演示。

我在网络上看到一个条目提到推出您自己的身份流程并将其连接到 OWIN 流程,但我完全不熟悉 OWIN 并且至少需要一些有关如何完成此操作的信息。 (我最初涉足 OWIN 项目没有产生任何结果)

有人知道吗?

最佳答案

更新: 我正在完全重写我的答案,因为我对这个过程了解了很多,并且意识到我的答案还远远不够完整。

首先我创建了我的实体,继承自身份的IdentyXXX类(这里只提供一个示例):

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using NTier.Web.Core.Interfaces.Common;
using NTier.Web.Core.Interfaces.DataModels;
using NTier.Web.Core.Interfaces.Stores;


namespace NTier.Web.DataAccess.Entities
{
    public sealed class MemberEntity : IdentityUser<Guid, MemberLogin, MemberRole, MemberClaim>,
        IMemberDataModel, IAuditable
    {

        public MemberEntity()
        {
            Id = Guid.NewGuid();
        }

        #region Overrides of IdentityUser<Guid,MemberLogin,MemberRole,MemberClaim>

        public override Guid Id
        {
            get { return base.Id; }
            set
            {
                base.Id = value != Guid.Empty ? value : base.Id;
            }
        }

        #region Overrides of IdentityUser<Guid,MemberLogin,MemberRole,MemberClaim>

        public override string PasswordHash
        {
            get { return base.PasswordHash; }
            set
            {
                base.PasswordHash = !string.IsNullOrWhiteSpace(value) ? value : base.PasswordHash ;
            }
        }

        #endregion

        #endregion

        public Guid Identity
        {
            get { return Id; }
            set
            {
                if (value != Guid.Empty)
                {
                    Id = value;
                }
            }
        }


        public string Moniker { get; set; }

        [MaxLength(256)]
        public string FirstName { get; set; }
        [MaxLength(256)]
        public string LastName { get; set; }
        [MaxLength(256)]
        public string Middle { get; set; }

        public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<MemberEntity, Guid> 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;
        }

        #region Implementation of IAuditable
        public DateTime DateTimeCreated { get; set; }
        public DateTime? DateTimeModified { get; set; }
        public DateTime? DateTimeDeleted { get; set; }
        public DateTime? DateTimeArchived { get; set; }
        public string CreatedBy { get; set; }
        public string ModifiedBy { get; set; }
        public string DeletedBy { get; set; }
        public string ArchivedBy { get; set; }
        public bool IsDeleted { get; set; }
        public bool IsArchived { get; set; }
        #endregion
    }
}

其次,我像这样覆盖了 DbContext 中的 OnModelCreating 方法:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            if (modelBuilder == null) throw new ArgumentNullException("modelBuilder");

            modelBuilder.Entity<WebSiteEntity>()
                        .HasKey(site => site.Identity)
                        .ToTable("WebSite");

            #region Security

            modelBuilder.Entity<MemberEntity>()
                        .ToTable("Member")
                        .HasMany(u => u.Roles)
                        .WithRequired()
                        .HasForeignKey(ur => ur.UserId);
            modelBuilder.Entity<MemberEntity>()
                        .HasMany(u => u.Claims)
                        .WithRequired()
                        .HasForeignKey(uc => uc.UserId);
            modelBuilder.Entity<MemberEntity>()
                        .HasMany(u => u.Logins)
                        .WithRequired()
                        .HasForeignKey(ul => ul.UserId);
            modelBuilder.Entity<MemberEntity>()
                        .Property(u => u.Moniker)
                        .HasMaxLength(50)
                        .HasColumnAnnotation("Index",
                                            new IndexAnnotation(new IndexAttribute("UserNameIndex")
                                                                {
                                                                    IsUnique = true,
                                                                    IsClustered = false,
                                                                    Order = 2
                                                                }))
                        .HasColumnAnnotation("Index",
                                            new IndexAnnotation(new IndexAttribute("MonikerIndex")
                                                                {
                                                                    IsUnique = true,
                                                                    IsClustered = false,
                                                                    Order = 1
                                                                }));
            modelBuilder.Entity<MemberEntity>()
                        .Property(u => u.LastName)
                        .HasMaxLength(256)
                        .HasColumnAnnotation("Index",
                                            new IndexAnnotation(new IndexAttribute("UserNameIndex")
                                                                {
                                                                    IsUnique = true,
                                                                    IsClustered = false,
                                                                    Order = 3
                                                                }))
                        .HasColumnAnnotation("Index",
                                            new IndexAnnotation(new IndexAttribute("MonikerIndex")
                                                                {
                                                                    IsUnique = true,
                                                                    IsClustered = false,
                                                                    Order = 2
                                                                }));
            ;
            modelBuilder.Entity<MemberEntity>()
                        .Property(u => u.FirstName)
                        .HasMaxLength(256)
                        .HasColumnAnnotation("Index",
                                            new IndexAnnotation(new IndexAttribute("UserNameIndex")
                                                                {
                                                                    IsUnique = true,
                                                                    IsClustered = false,
                                                                    Order = 4
                                                                }))
                        .HasColumnAnnotation("Index",
                                            new IndexAnnotation(new IndexAttribute("MonikerIndex")
                                                                {
                                                                    IsUnique = true,
                                                                    IsClustered = false,
                                                                    Order = 3
                                                                }));
            ;
            modelBuilder.Entity<MemberEntity>()
                        .Property(u => u.Middle)
                        .HasMaxLength(256);
            modelBuilder.Entity<MemberEntity>()
                        .Property(u => u.UserName)
                        .IsRequired()
                        .HasMaxLength(256)
                        .HasColumnAnnotation("Index",
                                            new IndexAnnotation(new IndexAttribute("UserNameIndex")
                                                                {
                                                                    IsUnique = true,
                                                                    IsClustered = false,
                                                                    Order = 1
                                                                }))
                        .HasColumnAnnotation("Index",
                                            new IndexAnnotation(new IndexAttribute("MonikerIndex")
                                                                {
                                                                    IsUnique = true,
                                                                    IsClustered = false,
                                                                    Order = 4
                                                                }));
            modelBuilder.Entity<MemberEntity>()
                        .Property(u => u.Email)
                        .HasMaxLength(256);
            modelBuilder.Entity<MemberRole>()
                        .HasKey(userRole => new
                                            {
                                                userRole.UserId,
                                                userRole.RoleId
                                            })
                        .ToTable("MemberRole");
            modelBuilder.Entity<MemberLogin>()
                        .HasKey(login => new
                                        {
                                            login.UserId,
                                            login.ProviderKey,
                                            login.LoginProvider
                                        })
                        .ToTable("MemberLogin");
            modelBuilder.Entity<MemberClaim>()
                        .ToTable("MemberClaim");
            modelBuilder.Entity<RoleEntity>()
                        .ToTable("Role");
            modelBuilder.Entity<RoleEntity>()
                        .Property(r => r.Name)
                        .IsRequired()
                        .HasMaxLength(256)
                        .HasColumnAnnotation("Index",
                                            new IndexAnnotation(new IndexAttribute("RoleNameIndex")
                                                                {
                                                                    IsUnique = true
                                                                }));
            modelBuilder.Entity<RoleEntity>()
                        .HasMany(r => r.Users)
                        .WithRequired()
                        .HasForeignKey(ur => ur.RoleId);

            #endregion

关于c# - 如何为新的 Microsoft.Asp.NET Identity (MVC5) 设置自定义架构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18948206/

相关文章:

c# - 动态类型和值类型如何工作?

c# - 当应用程序位于远程计算机上时,异常未定义

asp.net-mvc - Autofac:MVC 应用程序中 InstancePerRequest 和 InstancePerLifetimeScope 之间有什么区别

c# - 带有菜单/选项卡的 Xamarin Forms 轮播

c# - 是否可以在 C# 中的运行时创建/执行代码?

c# - 如何优化以下 linq to object 查询

c# - 如何将 SQL 日期转换为 DateTime?

c# - Web Config 转换问题

c# - 另一个相同类型的实体已经具有相同的主键值

c# - 解析简单日期时间