问题描述
我对ASP.NET Web API令牌认证中的声明有一些麻烦.
Im having some trouble with claims in ASP.NET Web API Token Auth.
基本上,我创建了一个具有某些声明的用户(值存储在AspNetUserClaim表中),但是在创建用户身份时,不会从数据库中提取这些声明.
Essentially I have created a user with some claims (values are being stored in the AspNetUserClaim table) but when the users identity is created, those claims are not being pulled from the database.
我的设置细分如下.
-
用户类:具有GenerateUserIdentityAsync方法(非常标准)和几个自定义属性:
User Class: Has a GenerateUserIdentityAsync method (pretty standard) and a couple of custom properties:
public class LibraryUser : IdentityUser{
//Add Custom Properties Here
public string Company { get; set; }
public string DisplayName { get; set; }
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<LibraryUser> 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;
}
}
我的DBContext声明了一些简单的名称更改,以使数据库看起来更好
My DBContext declares some simple name changes to make the DB look nicer
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
// Modify the Model creation properties..
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
//Rename Identity 2.0 Tables to something nicer..
modelBuilder.Entity<LibraryUser>().ToTable("LibraryUser");
modelBuilder.Entity<IdentityUser>().ToTable("LibraryUser");
modelBuilder.Entity<IdentityRole>().ToTable("Role");
modelBuilder.Entity<IdentityUserRole>().ToTable("UserRole");
modelBuilder.Entity<IdentityUserClaim>().ToTable("UserClaim");
modelBuilder.Entity<IdentityUserLogin>().ToTable("UserLogin");
}
我有一个名为LibraryUserManager的简单UserManager类,该类只是为我的用户类型扩展了UserManager.
I have a Simple UserManager class called LibraryUserManager which just extends UserManager for my user Type.
public class LibraryUserManager : UserManager<LibraryUser>
在播种数据库时(调用Update-Database时),将创建以下用户:
When the database is seeded (when calling Update-Database) the following user is created:
// -- Create Admin User, put in admin role..
LibraryUserManager userManager = new LibraryUserManager(new UserStore<LibraryUser>(context));
var user = new LibraryUser()
{
UserName = "[email protected]",
Email = "[email protected]",
DisplayName = "Administrator",
Company = "Test"
};
userManager.Create(user, "Password1.");
userManager.AddClaim(user.Id, new Claim(ClaimTypes.Role, "user"));
userManager.AddClaim(user.Id, new Claim(ClaimTypes.Role, "author"));
userManager.AddClaim(user.Id, new Claim(ClaimTypes.Role, "reviewer"));
userManager.AddClaim(user.Id, new Claim(ClaimTypes.Role, "admin"));
一旦运行此数据库,数据库就会拥有该用户(在LibraryUser表中)和Claims(在UserClaim表中)
Once this is run.. the database has the user (in the LibraryUser table) and the Claims (in the UserClaim table)
- 当我的自定义Auth Provider对用户进行身份验证时,可以找到他们(通过用户管理器),并且GenerateUserIdentityAsync称为:
显示该方法的其余部分...
EDIT : showing rest of that method...
var userManager = context.OwinContext.GetUserManager<LibraryUserManager>();
LibraryUser user = await userManager.FindAsync(context.UserName, context.Password);
//check if a user exists
if (user == null)
{
context.SetError("invalid_grant", "The user name or password is incorrect.");
return;
}
ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager, OAuthDefaults.AuthenticationType);
AuthenticationProperties properties = CreateProperties(user.UserName, user.DisplayName, oAuthIdentity);
AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties);
context.Validated(ticket);
-
创建属性的内容(如上所述):
Contents of create properties (called above):
public static AuthenticationProperties CreateProperties(string userName, string displayName, ClaimsIdentity oAuthIdentity)
{
IDictionary<string, string> data = new Dictionary<string, string>
{
{ "userName", userName },
{ "displayName", displayName },
{ "roles", string.Join(",", oAuthIdentity.Claims.Where(c => c.Type == ClaimTypes.Role).Select(c => c.Value).ToArray())}
};
return new AuthenticationProperties(data);
}
对用户进行身份验证时.我在LibraryUser.GenerateUserIdentityAsync(上面第1点下的代码)中设置了一个断点,CreateIdentityAsync返回的ClaimsIdentity.Claims集合中的唯一声明是默认声明(名称,identity_provider) ,security_stamp和另一个..)..我手动添加的声明不会从数据库中返回.
When the user is authed.. I have put a breakpoint in LibraryUser.GenerateUserIdentityAsync (code under point 1 above) and the only claims in the ClaimsIdentity.Claims collection returned by CreateIdentityAsync are the default ones (name, identity_provider, security_stamp and one other..) .. the claims I have manually added are not returned from the DB..
任何人都可以看到我所缺少的吗?
Can anyone see what I am missing??
如果您需要更多信息,我会尽力提供所有信息,请发表评论,我将修正我的问题.
I have tried to give all the info I can if you require more please comment and I will amend my question.
先谢谢您了:D
_L
推荐答案
OnModelCreating方法内部存在冲突的行:
There conflicting line is located inside the OnModelCreating method:
modelBuilder.Entity<LibraryUser>().ToTable("LibraryUser");
modelBuilder.Entity<IdentityUser>().ToTable("LibraryUser"); // <-- this one
因为您使用LibraryUser作为IdentityUser的派生类,所以不需要将IdentityUser显式映射到表.这样做搞乱了数据库中主键和外键的生成方式.
Because you are using the LibraryUser as a derived class from IdentityUser, you don't need to explicitly map IdentityUser to a table. Doing it messes up with how the primary and foreign keys are generated in the database.
这篇关于ASP Identity 2 + Web API令牌认证-持久声明未加载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!