自定义 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 ...
随机推荐
- Java 中常见的数据结构
1.数据结构有什么作用? 当使用 Java 里面的容器类时,你有没有想过,怎么 ArrayList 就像一个无限扩充的数组,也好像链表之类的.很好使用,这就是数据结构的用处,只不过你在不知不觉中使用了 ...
- linux if -d -e -f表达的意思
文件表达式-e filename 如果 filename存在,则为真-d filename 如果 filename为目录,则为真 -f filename 如果 filename为常规文件,则为真-L ...
- H5 66-清除浮动方式二
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- H5 37-背景缩写
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- BFC 原理
BFC:Block-level box + Forating + Context; ------->块元素 决定其子元素如何定位, ...
- 各种jar包
springframework下载地址:http://maven.springframework.org/release/org/springframework/spring/ commons开头的j ...
- MySQL分页时统计总记录行数并使用limit返回固定数目的记录
需求很简单:假设有一个user表,表中实际上有10000条数据,但是我不知道有多少条,我要从数据库中每次取20条数据显示,那么怎么完成呢? 方案一: 首先执行一个 select count(*) as ...
- Redis启动及密码修改
.cmd启动Redis: redis-server.exe redis.windows.conf #注意指定配置文件来启动 .cmd登陆redis redis-cli.exe -h -a .修改密码 ...
- Codeforces Round #546 (Div. 2)
http://codeforces.com/contest/1136 A #include <bits/stdc++.h> using namespace std; ; int N, K; ...
- [新三板摘牌]国资企业济南华光光电去年终止拟IPO今年摘牌新三板
国资企业济南华光光电去年终止拟IPO今年摘牌新三板 http://blog.sina.com.cn/s/blog_e32cfa770102ycku.html http://stock.qlmoney. ...