簡體   English   中英

ASP Identity 2 + Web API令牌認證-持久聲明未加載

[英]ASP Identity 2 + Web API Token Auth - Persistent claims not Loading

我在ASP.NET Web API令牌身份驗證中遇到了一些麻煩。

本質上,我已經創建了一個具有某些聲明的用戶(值存儲在AspNetUserClaim表中),但是在創建用戶身份時,不會從數據庫中提取這些聲明。

我的設置細分如下。

  1. 用戶類:具有GenerateUserIdentityAsync方法(非常標准)和幾個自定義屬性:

     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; } } 
  2. 我的DBContext聲明了一些簡單的名稱更改,以使數據庫看起來更好

     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"); } 
  3. 我有一個名為LibraryUserManager的簡單UserManager類,該類只是為我的用戶Type擴展了UserManager。

     public class LibraryUserManager : UserManager<LibraryUser> 
  4. 播種數據庫時(調用Update-Database時),將創建以下用戶:

     // -- Create Admin User, put in admin role.. LibraryUserManager userManager = new LibraryUserManager(new UserStore<LibraryUser>(context)); var user = new LibraryUser() { UserName = "admin@admin.com", Email = "admin@admin.com", 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")); 
  5. 一旦運行,數據庫將擁有用戶(在LibraryUser表中)和Claims(在UserClaim表中)

在此處輸入圖片說明

在此處輸入圖片說明

  1. 當我的自定義Auth Provider對用戶進行身份驗證時,可以找到他們(通過用戶管理器),然后調用GenerateUserIdentityAsync:

編輯:顯示該方法的其余部分...

    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. 創建屬性的內容(以上所述):

     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); } 
  2. 當對用戶進行身份驗證時。我在LibraryUser.GenerateUserIdentityAsync(上面第1點下的代碼)中放置了一個斷點,CreateIdentityAsync返回的ClaimsIdentity.Claims集合中的唯一聲明是默認聲明(名稱,identity_provider,security_stamp等)。 .. ..我手動添加的聲明未從數據庫返回。

誰能看到我所缺少的?

我已嘗試提供所有可能的信息,如果您需要更多信息,請發表評論,我將修正我的問題。

提前致謝

_L

在OnModelCreating方法內部存在沖突的行:

modelBuilder.Entity<LibraryUser>().ToTable("LibraryUser");
modelBuilder.Entity<IdentityUser>().ToTable("LibraryUser"); // <-- this one

因為您使用LibraryUser作為IdentityUser的派生類,所以不需要將IdentityUser顯式映射到表。 這樣做搞亂了數據庫中主鍵和外鍵的生成方式。

放入數據庫(在AddClaim()AddClaim() )和包含在令牌中的聲明是不同的。 您必須將聲明數據手動放在繼承的OAuthAuthorizationServerProvider類中,該類由ASP.NET在提供程序文件夾或您創建的任何oauth提供程序中提供默認的ApplicatoinOAuthProvider.cs。

在那里,重寫的GrantResourceOwnerCredentials()方法使AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties); 為了將索償放入代幣中

然后,Windows Identity將從您放置的令牌中讀取聲明。

    public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        using (var userManager = _container.GetInstance<ApplicationUserManager>())
        {
            var user = await userManager.FindAsync(context.UserName, context.Password);
            if (user == null)
            {
                context.SetError("invalid_grant", "The user name or password is incorrect.");
                return;
            }

            ClaimsIdentity oAuthIdentity = await userManager.CreateIdentityAsync(user,
                context.Options.AuthenticationType);
            ClaimsIdentity cookiesIdentity = await userManager.CreateIdentityAsync(user,
                CookieAuthenticationDefaults.AuthenticationType);
            AuthenticationProperties properties = CreateProperties(user);

            // Below line adds additional claims in token.
            AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties);
            context.Validated(ticket);
            context.Request.Context.Authentication.SignIn(cookiesIdentity);
        }
    }


    public static AuthenticationProperties CreateProperties(AspNetUser user)
    {
        IDictionary<string, string> data = new Dictionary<string, string>
        {
            {"Id", user.Id.ToString(CultureInfo.InvariantCulture)},
            {"http://axschema.org/namePerson", user.Nickname,},
            {"http://axschema.org/contact/email", user.Email,},
        };

        return new AuthenticationProperties(data);
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM