Skip to content

Commit f8a455e

Browse files
committed
Added ASP.NET Identity Multitenancy code
1 parent cac627e commit f8a455e

File tree

4 files changed

+280
-1
lines changed

4 files changed

+280
-1
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
namespace QuickAndEasyAspNetIdentityMultitenanc.Identity
2+
{
3+
using System;
4+
5+
using Microsoft.AspNet.Identity.EntityFramework;
6+
7+
public class ApplicationUser : ApplicationUser<string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>
8+
{
9+
public ApplicationUser()
10+
{
11+
Id = Guid.NewGuid().ToString();
12+
}
13+
14+
public ApplicationUser(string userName)
15+
: this()
16+
{
17+
UserName = userName;
18+
}
19+
}
20+
21+
public class ApplicationUser<TKey, TLogin, TRole, TClaim> : IdentityUser<TKey, TLogin, TRole, TClaim>
22+
where TLogin : IdentityUserLogin<TKey>
23+
where TRole : IdentityUserRole<TKey>
24+
where TClaim : IdentityUserClaim<TKey>
25+
{
26+
public ApplicationUser()
27+
: base()
28+
{
29+
}
30+
31+
public int TenantId { get; set; }
32+
33+
}
34+
35+
36+
}
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
namespace QuickAndEasyAspNetIdentityMultitenanc.Identity
2+
{
3+
using System;
4+
using System.Collections.Generic;
5+
using System.ComponentModel.DataAnnotations.Schema;
6+
using System.Data.Common;
7+
using System.Data.Entity;
8+
using System.Data.Entity.Infrastructure;
9+
using System.Data.Entity.Infrastructure.Annotations;
10+
using System.Data.Entity.Validation;
11+
using System.Linq;
12+
13+
using Microsoft.AspNet.Identity.EntityFramework;
14+
15+
public class ApplicationUserDbContext :
16+
ApplicationUserDbContext<ApplicationUser, IdentityRole, string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>
17+
{
18+
public ApplicationUserDbContext()
19+
: this("DefaultConnection")
20+
{
21+
}
22+
23+
public ApplicationUserDbContext(string nameOrConnectionString)
24+
: base(nameOrConnectionString)
25+
{
26+
}
27+
28+
public ApplicationUserDbContext(DbConnection existingConnection, DbCompiledModel model, bool contextOwnsConnection)
29+
: base(existingConnection, model, contextOwnsConnection)
30+
{
31+
}
32+
33+
public ApplicationUserDbContext(DbCompiledModel model)
34+
: base(model)
35+
{
36+
}
37+
38+
public ApplicationUserDbContext(DbConnection existingConnection, bool contextOwnsConnection)
39+
: base(existingConnection, contextOwnsConnection)
40+
{
41+
}
42+
43+
public ApplicationUserDbContext(string nameOrConnectionString, DbCompiledModel model)
44+
: base(nameOrConnectionString, model)
45+
{
46+
}
47+
}
48+
49+
public class ApplicationUserDbContext<TUser> :
50+
ApplicationUserDbContext<TUser, IdentityRole, string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>
51+
where TUser : ApplicationUser
52+
{
53+
public ApplicationUserDbContext()
54+
: this("DefaultConnection")
55+
{
56+
}
57+
58+
public ApplicationUserDbContext(string nameOrConnectionString)
59+
: base(nameOrConnectionString)
60+
{
61+
}
62+
63+
public ApplicationUserDbContext(DbConnection existingConnection, DbCompiledModel model, bool contextOwnsConnection)
64+
: base(existingConnection, model, contextOwnsConnection)
65+
{
66+
}
67+
68+
public ApplicationUserDbContext(DbCompiledModel model)
69+
: base(model)
70+
{
71+
}
72+
73+
public ApplicationUserDbContext(DbConnection existingConnection, bool contextOwnsConnection)
74+
: base(existingConnection, contextOwnsConnection)
75+
{
76+
}
77+
78+
public ApplicationUserDbContext(string nameOrConnectionString, DbCompiledModel model)
79+
: base(nameOrConnectionString, model)
80+
{
81+
}
82+
}
83+
84+
public class ApplicationUserDbContext<TUser, TRole, TKey, TUserLogin, TUserRole, TUserClaim> :
85+
IdentityDbContext<TUser, TRole, TKey, TUserLogin, TUserRole, TUserClaim>
86+
where TUser : ApplicationUser<TKey, TUserLogin, TUserRole, TUserClaim>
87+
where TRole : IdentityRole<TKey, TUserRole>
88+
where TUserLogin : IdentityUserLogin<TKey>
89+
where TUserRole : IdentityUserRole<TKey>
90+
where TUserClaim : IdentityUserClaim<TKey>
91+
{
92+
public ApplicationUserDbContext()
93+
: this("DefaultConnection")
94+
{
95+
}
96+
97+
public ApplicationUserDbContext(string nameOrConnectionString)
98+
: base(nameOrConnectionString)
99+
{
100+
}
101+
102+
public ApplicationUserDbContext(DbConnection existingConnection, DbCompiledModel model, bool contextOwnsConnection)
103+
: base(existingConnection, model, contextOwnsConnection)
104+
{
105+
}
106+
107+
public ApplicationUserDbContext(DbCompiledModel model)
108+
: base(model)
109+
{
110+
}
111+
112+
public ApplicationUserDbContext(DbConnection existingConnection, bool contextOwnsConnection)
113+
: base(existingConnection, contextOwnsConnection)
114+
{
115+
}
116+
117+
public ApplicationUserDbContext(string nameOrConnectionString, DbCompiledModel model)
118+
: base(nameOrConnectionString, model)
119+
{
120+
}
121+
122+
protected override void OnModelCreating(DbModelBuilder modelBuilder)
123+
{
124+
base.OnModelCreating(modelBuilder);
125+
126+
var user = modelBuilder.Entity<TUser>();
127+
128+
user.Property(u => u.UserName)
129+
.IsRequired()
130+
.HasMaxLength(256)
131+
.HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute("UserNameIndex") { IsUnique = true, Order = 1}));
132+
133+
user.Property(u => u.TenantId)
134+
.IsRequired()
135+
.HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute("UserNameIndex") { IsUnique = true, Order = 2 }));
136+
}
137+
138+
protected override DbEntityValidationResult ValidateEntity(DbEntityEntry entityEntry, IDictionary<object, object> items)
139+
{
140+
if (entityEntry != null && entityEntry.State == EntityState.Added)
141+
{
142+
var errors = new List<DbValidationError>();
143+
var user = entityEntry.Entity as TUser;
144+
145+
if (user != null)
146+
{
147+
if (this.Users.Any(u => string.Equals(u.UserName, user.UserName) && u.TenantId == user.TenantId))
148+
{
149+
errors.Add(
150+
new DbValidationError("User", string.Format("Username {0} is already taken for AppId {1}", user.UserName, user.TenantId)));
151+
}
152+
153+
if (this.RequireUniqueEmail && this.Users.Any(u => string.Equals(u.Email, user.Email) && u.TenantId == user.TenantId))
154+
{
155+
errors.Add(
156+
new DbValidationError(
157+
"User",
158+
string.Format("Email Address {0} is already taken for AppId {1}", user.UserName, user.TenantId)));
159+
}
160+
}
161+
else
162+
{
163+
var role = entityEntry.Entity as TRole;
164+
165+
if (role != null && this.Roles.Any(r => string.Equals(r.Name, role.Name)))
166+
{
167+
errors.Add(new DbValidationError("Role", string.Format("Role {0} already exists", role.Name)));
168+
}
169+
}
170+
171+
if (errors.Any())
172+
{
173+
return new DbEntityValidationResult(entityEntry, errors);
174+
}
175+
}
176+
177+
return new DbEntityValidationResult(entityEntry, new List<DbValidationError>());
178+
}
179+
}
180+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
namespace QuickAndEasyAspNetIdentityMultitenanc.Identity
2+
{
3+
using System;
4+
using System.Data.Entity;
5+
using System.Threading.Tasks;
6+
7+
using Microsoft.AspNet.Identity.EntityFramework;
8+
9+
public class ApplicationUserStore<TUser> :
10+
ApplicationUserStore<TUser, IdentityRole, string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>
11+
where TUser : ApplicationUser
12+
{
13+
public ApplicationUserStore()
14+
: this(new IdentityDbContext())
15+
{
16+
DisposeContext = true;
17+
}
18+
19+
public ApplicationUserStore(DbContext context)
20+
: base(context)
21+
{
22+
}
23+
}
24+
25+
public class ApplicationUserStore<TUser, TRole, TKey, TUserLogin, TUserRole, TUserClaim> :
26+
UserStore<TUser, TRole, TKey, TUserLogin, TUserRole, TUserClaim>
27+
where TKey : IEquatable<TKey>
28+
where TUser : ApplicationUser<TKey, TUserLogin, TUserRole, TUserClaim>
29+
where TRole : IdentityRole<TKey, TUserRole>
30+
where TUserLogin : IdentityUserLogin<TKey>, new()
31+
where TUserRole : IdentityUserRole<TKey>, new()
32+
where TUserClaim : IdentityUserClaim<TKey>, new()
33+
{
34+
public ApplicationUserStore(DbContext context)
35+
: base(context)
36+
{
37+
}
38+
39+
public int TenantId { get; set; }
40+
41+
public override Task CreateAsync(TUser user)
42+
{
43+
if (user == null)
44+
{
45+
throw new ArgumentNullException("user");
46+
}
47+
48+
user.TenantId = this.TenantId;
49+
50+
return base.CreateAsync(user);
51+
}
52+
53+
public override Task<TUser> FindByEmailAsync(string email)
54+
{
55+
return this.GetUserAggregateAsync(u => u.Email.ToUpper() == email.ToUpper() && u.TenantId == this.TenantId);
56+
}
57+
58+
public override Task<TUser> FindByNameAsync(string userName)
59+
{
60+
return this.GetUserAggregateAsync(u => u.UserName.ToUpper() == userName.ToUpper() && u.TenantId == this.TenantId);
61+
}
62+
}
63+
}

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
# Blog-Example-Classes
2-
Example code from my blog
2+
Full example code from my blog - [www.scottbrady91.com](https://www.scottbrady91.com)

0 commit comments

Comments
 (0)