自定义 ASP.NET Identity Data Model with EF
One of the first issues you will likely encounter when getting started with ASP.NET Identity centers on customizing the underlying data model. The Entity Framework provider uses Code-First to generate the data model and, initially, it may seem as if it is imposing its model upon your application. Fortunately, since the implementation of the provider uses Code-First, we can make significant customizations to the model and still take advantage of the features that ASP.NET Identity and EF provide.
In part one of this series, we will customize the ASP.NET Identity data model by simply changing the default schema and renaming the tables. In part two of this series, we will add audit fields to some of the tables and change the primary key data types from GUIDs to integers.
To get started, let’s generate the default data model to see what we are working with:
- Start by creating a new ASP.NET MVC and/or Web API project. Be sure the Authentication Mode is set to “Individual User Accounts” so the project template pulls in the required references, as well as the scaffolding for the default security model.
- Update the default connection string (“DefaultConnection”) in the web.config to point to your SQL Server database.
- Build and run the application.
Next, navigate to the login page and attempt to sign in with any credentials. Your login attempt will fail because no accounts are registered, but the Entity Framework should have generated the default data model for users, roles, and claims. If you check the database, you will find something similar to the following:
That is all well and good and if you have worked with the Membership Provider for .NET, you should be reasonably comfortable with what you see. However, we are interested in customizing the model; so let’s get started by renaming the tables and moving them into our application schema.
Step 1: Create the object model
To get started, add the following classes to your project. These classes form the object model that will be mapped to the data model. If you are following along in the attached sample project, you will find these classes under the NAM_Sample_Pt1.Models namespace.
ApplicationUserRole.cs
public class ApplicationUserRole : IdentityUserRole { }
ApplicationRole.cs
public class ApplicationRole : IdentityRole<string, applicationuserrole=""> { }
ApplicationUserClaim.cs
public class ApplicationUserClaim : IdentityUserClaim { }
ApplicationUserLogin.cs
public class ApplicationUserLogin : IdentityUserLogin { }
IdentityModels.cs
Update the ApplicationUser class with the following:
public class ApplicationUser : IdentityUser<string, applicationuserlogin,="" applicationuserrole,="" applicationuserclaim="">
{
public async Task GenerateUserIdentityAsync(ApplicationUserManager 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;
}
}
Step 2: Create the EF data context
Create a new security data context in IdentityModels.cs according to the following definition:
public class ApplicationDbContext : IdentityDbContext<applicationuser, applicationrole,="" string,="" applicationuserlogin,="" applicationuserrole,="" applicationuserclaim="">
{
public ApplicationDbContext() : base("DefaultConnection") { } public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
Note that the data context inherits from IdentityDbContext, which is the generic base data context that is included in the EF Provider for Identity. IdentityDbContext includes several generic type parameters, which should be set to the various types defined in the object model we created in the previous step.
We will revisit the data context once we have finished configuring the objects required to customize the model; however, be aware that this is where we will implement the fluent mapping.
Step 3: Create a custom user store
In ASP.NET Identity 2.0 user stores are the repositories for user data. The Entity Framework implementation of the user store requires a data context. Here is the implementation of our custom user store:
public class ApplicationUserStore :
UserStore<applicationuser, applicationrole,="" string,="" applicationuserlogin,="" applicationuserrole,="" applicationuserclaim="">,
IUserStore,
IDisposable
{
public ApplicationUserStore(ApplicationDbContext context) : base(context) { }
}
Step 4: Modify ApplicationUserManager to use the new object model
There are several lines in the ApplicationUserManager (included in the default project template) that must be modified. First, in the static Create() method, modify the creation of the ApplicationUserManager so that it takes an ApplicationUserStore and ApplicationDbContext as arguments in its constructor, as such:
var manager = new ApplicationUserManager(new ApplicationUserStore(context.Get()));
Step 5: Create the fluent mapping
We are finally ready to map our objects to our new data model. Begin by overriding OnModelCreating() in ApplicationDbContext . We will use EF Fluent API to map each of the five objects in our security object model to new tables in a new schema. The full fluent API mapping is included below:
protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
{
modelBuilder.HasDefaultSchema("NAM"); modelBuilder.Entity().Map(c =>
{
c.ToTable("UserLogin");
c.Properties(p => new
{
p.UserId,
p.LoginProvider,
p.ProviderKey
});
}).HasKey(p => new { p.LoginProvider, p.ProviderKey, p.UserId }); // Mapping for ApiRole
modelBuilder.Entity().Map(c =>
{
c.ToTable("Role");
c.Property(p => p.Id).HasColumnName("RoleId");
c.Properties(p => new
{
p.Name
});
}).HasKey(p => p.Id);
modelBuilder.Entity().HasMany(c => c.Users).WithRequired().HasForeignKey(c => c.RoleId);
modelBuilder.Entity().Map(c =>
{
c.ToTable("User");
c.Property(p => p.Id).HasColumnName("UserId");
c.Properties(p => new
{
p.AccessFailedCount,
p.Email,
p.EmailConfirmed,
p.PasswordHash,
p.PhoneNumber,
p.PhoneNumberConfirmed,
p.TwoFactorEnabled,
p.SecurityStamp,
p.LockoutEnabled,
p.LockoutEndDateUtc,
p.UserName
});
}).HasKey(c => c.Id);
modelBuilder.Entity().HasMany(c => c.Logins).WithOptional().HasForeignKey(c => c.UserId);
modelBuilder.Entity().HasMany(c => c.Claims).WithOptional().HasForeignKey(c => c.UserId);
modelBuilder.Entity().HasMany(c => c.Roles).WithRequired().HasForeignKey(c => c.UserId); modelBuilder.Entity().Map(c =>
{
c.ToTable("UserRole");
c.Properties(p => new
{
p.UserId,
p.RoleId
});
})
.HasKey(c => new { c.UserId, c.RoleId }); modelBuilder.Entity().Map(c =>
{
c.ToTable("UserClaim");
c.Property(p => p.Id).HasColumnName("UserClaimId");
c.Properties(p => new
{
p.UserId,
p.ClaimValue,
p.ClaimType
});
}).HasKey(c => c.Id);
}
You are now ready to build and run the project. As before, navigate to the login page and attempt to sign in, which will force the creation of the new data model. You should now see the model in the custom schema with the table names we declared in the fluent mapping.
In part two of this series we will add audit fields to some of the tables and change the primary key data types from GUIDs to integers.
Attachments
自定义 ASP.NET Identity Data Model with EF的更多相关文章
- ASP.NET MVC - 安全、身份认证、角色授权和ASP.NET Identity
ASP.NET MVC - 安全.身份认证.角色授权和ASP.NET Identity ASP.NET MVC内置的认证特性 AuthorizeAttribute特性(System.Web.Mvc)( ...
- 【ASP.NET Identity系列教程(一)】ASP.NET Identity入门
注:本文是[ASP.NET Identity系列教程]的第一篇.本系列教程详细.完整.深入地介绍了微软的ASP.NET Identity技术,描述了如何运用ASP.NET Identity实现应用程序 ...
- ASP.NET Identity 一 (转载)
来源:http://www.cnblogs.com/r01cn/p/5194257.html 注:本文是[ASP.NET Identity系列教程]的第一篇.本系列教程详细.完整.深入地介绍了微软的A ...
- ASP.NET Identity系列教程-2【Identity入门】
https://www.cnblogs.com/r01cn/p/5177708.html13 Identity入门 Identity is a new API from Microsoft to ma ...
- [转]Creating an Entity Framework Data Model for an ASP.NET MVC Application (1 of 10)
本文转自:http://www.asp.net/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/creating-a ...
- 用于Simple.Data的ASP.NET Identity Provider
今天推举的这篇文章,本意不是要推举文章的内容,而是据此介绍一下Simple.Data这个很有意思的类ORM工具. 现在大家在.NET开发中如果需要进行数据访问,那么基本都会使用一些ORM工具,比如微软 ...
- 【分分钟内搭建一个带用户系统的博客程序(一)用户系统】asp.net core的Identity真香,EF真香!
不用不知道,一用香到爆. 老哥是个屌丝前端,但也想写点web应用耍一耍.之前弄过了NodeJs,也弄过JAVA,最近由于写游戏的原因用C#,索性上手一波asp.net core. 这篇博客记录的是,如 ...
- EF,ADO.NET Entity Data Model简要的笔记
1. 新建一个项目,添加一个ADO.NET Entity Data Model的文件,此文件会生成所有的数据对象模型,如果是用vs2012生的话,在.Designer.cs里会出现“// Defaul ...
- How to: Supply Initial Data for the Entity Framework Data Model 如何:为EF数据模型提供初始数据
After you have introduced a data model, you may need to have the application populate the database w ...
随机推荐
- windows使用.NET CORE下创建MVC,发布到linux运行
1.在有dotnet core 的环境下,打开控制台.创建文件夹demo1 2.创建MVC程序 3.创建完成 4.使用记事本修改一下HomeController 修改端口 5.发布 6.压缩发布的文件 ...
- Cgroups 与 Systemd
Cgroups 是 linux 内核提供的一种机制,如果你还不了解 cgroups,请参考前文<Linux cgroups 简介>先了解 cgroups.当 Linux 的 init 系统 ...
- 使用 OpenSSL 创建私有 CA:3 用户证书
OpenSSL 创建私有 CA 三部曲:使用 OpenSSL 创建私有 CA:1 根证书使用 OpenSSL 创建私有 CA:2 中间证书使用 OpenSSL 创建私有 CA:3 用户证书 在前文&l ...
- OO最后一次作业
终于开始最后一次作业了,是时候为这学期oo画一个圆满的局句号了. 回首这学期的OO经历,一路走来,经过了开始对面向对象的初步接触,然后就是充满痛苦回忆的多线程,接下来到了令人焦头烂额的规格设计,最后是 ...
- H5 20-属性选择器上
20-属性选择器上 --> 我是段落1 我是段落2 我是段落3 我是段落4 我是段落5 <!DOCTYPE html> <html lang="en"> ...
- Minesweeper
你玩过扫雷吗?这个可爱的小游戏带有一个我们记不住名字的操作系统.游戏的目标是找到所有地雷在M x N场中的位置.游戏在一个正方形中显示一个数字,它告诉你在这个正方形附近有 多少个地雷.每个方块最多有八 ...
- hibernate坑边闲话3
could not initialize proxy - no Session] with root cause org.hibernate.LazyInitializationException: ...
- matplotlib 入门之Usage Guide
文章目录 Usage Guide plotting函数的输入 matplotlib, pyplot, pylab, 三者的联系 Coding style Backends 后端 matplotlib教 ...
- echarts x轴 增加滚动条
charts x轴 增加滚动条 在option 配置项中添加 [ dataZoom 中配置 ] 设置x轴滚动条 效果图: 动态拖动 以下参考代码 dataZoom配置 官网写法 option = { ...
- C# 和 c++的语法不同点
GC Garbage Collection 垃圾回收器 自动释放资源 关键字: new 1.创建对象 2.隐藏从父类继承的同名函数 using 1.引用命名空间 2. using(FileStrea ...