【问题标题】:Identity Core Get Name & Other fields身份核心获取名称和其他字段
【发布时间】:2018-03-11 16:07:51
【问题描述】:

我注意到使用 Identity core 我可以通过以下方式获取名称字段:

HttpContext.User.Identity.Name

我不明白这个值是如何设置的,以及如何向它添加其他字段,例如 MyCustomField 或 Address 或 Id。我一直在查看开源 https://github.com/aspnet/Identity 但是,我似乎无法弄清楚。理想情况下,我希望在身份项目之外和我自己的项目中这样做。

有人可以向我解释这是如何工作的以及如何添加更多字段吗?

编辑:

如果我想添加地址,我会编写以下代码:

public static class IdentityExtensions
{
     public static string GetAddress(this IIdentity identity)
     {
         return ((ClaimsIdentity) identity).FindFirst("Address").Value;
     }
 }

现在上面的代码允许我从声明中提取地址值,但我不明白如何获取保存在那里的值。

如果我使用的是 EF,那么我会在 GenerateUserIdentityAsync 方法下这样做。但是,我不是,我正在使用 dapper,所以我试图了解它是如何工作的。什么时候我会从数据库中读取信息并将其添加到声明中(我知道这会在登录时发生,但是在代码中会发生这种情况,当前名称是如何填写的)?

【问题讨论】:

标签: asp.net-core .net-core asp.net-core-mvc asp.net-identity identity


【解决方案1】:

我通过执行以下操作来完成此操作:

1 - 向数据库中名为 [staff_id] 的 [AspNetUsers] 表添加了一个新列。

2 - 创建了一个继承自 IdentityUser 的 ApplicationUser 类

public class ApplicationUser : IdentityUser
{
 public ApplicationUser(){ }
 public int staff_id { get; set; }
}

3 - 创建了一个继承 UserClaimsPrincipalFactory 并覆盖 CreateAsync 方法的类 AppClaimsPrincipalFactory。

public class AppClaimsPrincipalFactory : UserClaimsPrincipalFactory<ApplicationUser, IdentityRole>
{
    public AppClaimsPrincipalFactory(UserManager<ApplicationUser> userManager,
                                     RoleManager<IdentityRole> roleManager,
                                     IOptions<IdentityOptions> optionsAccessor
                                    ): base(userManager, roleManager, optionsAccessor){  }
    public async override Task<ClaimsPrincipal> CreateAsync(ApplicationUser user)
    {
        var principal = await base.CreateAsync(user);

        ((ClaimsIdentity)principal.Identity).AddClaims(new[] {
            new Claim("staff_id",user.staff_id.ToString())
        });

        return principal;
    }
}

4 - 修改 Startup.cs ConfigureServices 方法,添加代码以使用我的本地 AppClaimsPrincipalFactory 类在登录时自定义用户

//add Entity Framework 
services.AddDbContext<MyDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("MyConnectionString")));

//add Identity framework, specify which DbContext to use
services.AddIdentity<ApplicationUser, IdentityRole>()
                .AddEntityFrameworkStores<MyDbContext>()
                .AddDefaultTokenProviders();

//add local AppClaimsPrincipalFactory class to customize user
services.AddScoped<IUserClaimsPrincipalFactory<ApplicationUser>, AppClaimsPrincipalFactory>();

5 - 最后我按如下方式访问声明,可能有更好的方法,但这就是我访问经过身份验证的用户的 staff_id 的方式。

int iStaffId;
if(!Int32.TryParse(User.FindFirst("staff_id").Value, out iStaffId))
{
 //throw an error because the staff_id claim should be present in iStaffId
}

我发现其他一些有用的资源如下。祝你好运。

How to extend ASP.NET Core Identity user

ASP.NET Core Identity 3.0 : Modifying the Identity Database

Configure the ASP.NET Core Identity primary key data type

【讨论】:

  • 感谢您的详尽帖子。我有点困惑的是,您在 CreateAsync 方法上创建了一个声明。这意味着这些声明是在首次创建用户时创建的。那么你的索赔然后被写入数据库索赔表?当值改变时会发生什么,你如何更新它?
  • 我有一个编辑表单来添加/编辑新用户 [AspNetUsers]。我的表单有一个表中的 staff_id 列的下拉列表。现在,当我创建的该用户尝试登录身份框架时,会验证用户名和密码是否与表中的记录相对应。如果用户成功登录,自定义声明 staff_id 将加载/存储在经过身份验证的用户上。这有帮助吗?回答您的问题:每次用户登录应用程序时都会创建声明,没有声明存储在另一个表中。您可以通过更新数据库中的记录来更改索赔的价值。
猜你喜欢
  • 1970-01-01
  • 2019-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-11
  • 1970-01-01
  • 2018-07-04
  • 1970-01-01
相关资源
最近更新 更多