本文介绍了ASP Identity 2 + Web API令牌认证-持久声明未加载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对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.

我的设置细分如下.

  1. 用户类:具有GenerateUserIdentityAsync方法(非常标准)和几个自定义属性:

  1. 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)

    1. 当我的自定义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);
    
    1. 创建属性的内容(如上所述):

    1. 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令牌认证-持久声明未加载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

  • 09-11 20:44