如何扩展User.Identity的可用属性

我使用MVC5身份2.0用户login到我的网站,身份validation详细信息存储在SQL数据库中。 Asp.net Identity已经以标准的方式实现,可以在许多在线教程中find。

IdentityModels中的ApplicationUser类已扩展为包含一些自定义属性,如整数OrganizationId。 这个想法是,可以创build许多用户,并将其分配给一个通用的组织用于数据库关系目的。

public class ApplicationUser : IdentityUser { public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager) { // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie); // Add custom user claims here return userIdentity; } //Extended Properties public DateTime? BirthDate { get; set; } public long? OrganizationId { get; set; } //Key Mappings [ForeignKey("OrganizationId")] public virtual Organization Organization { get; set; } } 

如何从控制器中检索当前login用户的OrganizationId属性? 当用户login后,是否可以通过一个方法获得这个值,或者每次控制器方法执行时,我是否总是从数据库中检索OrganizationId(基于UserId)?

在网上阅读我已经看到我需要使用以下来获取loginUserId等

 using Microsoft.AspNet.Identity; ... User.Identity.GetUserId(); 

但是,OrganizationId不是User.Identity中可用的属性。 我是否需要扩展User.Identity以包含OrganizationId属性? 如果是的话,我该怎么做呢。

我经常需要OrganizationId的原因是许多表查询依赖于OrganizationId来检索与login用户关联的组织相关的数据。

每当你想用上面的问题来扩展User.Identity的属性时,首先将这些属性添加到ApplicationUser类中,如下所示:

 public class ApplicationUser : IdentityUser { public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager) { // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie); // Add custom user claims here return userIdentity; } // Your Extended Properties public long? OrganizationId { get; set; } } 

那么你需要的是创build一个像这样的扩展方法(我在一个新的扩展文件夹中创build我的):

 namespace App.Extensions { public static class IdentityExtensions { public static string GetOrganizationId(this IIdentity identity) { var claim = ((ClaimsIdentity)identity).FindFirst("OrganizationId"); // Test for null to avoid issues during local testing return (claim != null) ? claim.Value : string.Empty; } } } 

在ApplicationUser类中创build标识时,只需添加Claim – > OrganizationId,如下所示:

  public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager) { // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie); // Add custom user claims here => this.OrganizationId is a value stored in database against the user userIdentity.AddClaim(new Claim("OrganizationId", this.OrganizationId.ToString())); return userIdentity; } 

一旦你添加了声明,并有你的扩展方法,使其作为您的User.Identity属性, 添加使用语句在您要访问的页面/文件

在我的情况下: using App.Extensions; 在一个控制器和@using. App.Extensions 使用.cshtml查看文件的@using. App.Extensions

编辑:

你也可以做,以避免在每个视图中添加使用语句是去视图文件夹,并在那里findWeb.config文件。 现在查找标签并在其中添加扩展名称空间,如下所示:

 <add namespace="App.Extensions"> 

保存你的文件,你就完成了。 现在每个视图都会知道你的扩展。

您可以访问扩展方法:

 var orgId = User.Identity.GetOrganizationId(); 

希望帮助任何人:)

我正在寻找相同的解决scheme,帕维尔给了我99%的答案。 我唯一需要扩展才能显示的是将下面的Razor代码添加到cshtml(view)页面中:

@using programname.Models.Extensions

我正在寻找名字,在用户login后显示在我的NavBar的右上angular。

我以为我会发布这incase它帮助别人,所以这里是我的代码:

我创build了一个名为扩展(在我的模型文件夹下)的新文件夹,并创build了上面指定的Pawel的新类: IdentityExtensions.cs

 using System.Security.Claims; using System.Security.Principal; namespace ProgramName.Models.Extensions { public static class IdentityExtensions { public static string GetUserFirstname(this IIdentity identity) { var claim = ((ClaimsIdentity)identity).FindFirst("FirstName"); // Test for null to avoid issues during local testing return (claim != null) ? claim.Value : string.Empty; } } } 

IdentityModels.cs

 public class ApplicationUser : IdentityUser { //Extended Properties public string FirstName { get; internal set; } public string Surname { get; internal set; } public bool isAuthorized { get; set; } public bool isActive { get; set; } public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager) { // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie); // Add custom user claims here userIdentity.AddClaim(new Claim("FirstName", this.FirstName)); return userIdentity; } } 

然后在我的_LoginPartial.cshtml (在Views/Shared文件夹)我添加@using.ProgramName.Models.Extensions

然后,我将这个改变添加到将在login之后使用用户名的代码行:

@Html.ActionLink("Hello " + User.Identity.GetUserFirstname() + "!", "Index", "Manage", routeValues: null, htmlAttributes: new { title = "Manage" })

也许这有助于其他人的下线。

看看John Atten: ASP.NET Identity 2.0:自定义用户和angular色这个伟大的博客文章

它在整个过程中有很好的一步一步的信息。 阅读它:)

这里有一些基础知识。

通过添加新的属性(即地址,城市,州等)扩展默认的ApplicationUser类:

 public class ApplicationUser : IdentityUser { public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager) { var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie); return userIdentity; } public string Address { get; set; } public string City { get; set; } public string State { get; set; } // Use a sensible display name for views: [Display(Name = "Postal Code")] public string PostalCode { get; set; } // Concatenate the address info for display in tables and such: public string DisplayAddress { get { string dspAddress = string.IsNullOrWhiteSpace(this.Address) ? "" : this.Address; string dspCity = string.IsNullOrWhiteSpace(this.City) ? "" : this.City; string dspState = string.IsNullOrWhiteSpace(this.State) ? "" : this.State; string dspPostalCode = string.IsNullOrWhiteSpace(this.PostalCode) ? "" : this.PostalCode; return string.Format("{0} {1} {2} {3}", dspAddress, dspCity, dspState, dspPostalCode); } } 

然后,将您的新属性添加到您的RegisterViewModel。

  // Add the new address properties: public string Address { get; set; } public string City { get; set; } public string State { get; set; } 

然后更新注册视图以包含新的属性。

  <div class="form-group"> @Html.LabelFor(m => m.Address, new { @class = "col-md-2 control-label" }) <div class="col-md-10"> @Html.TextBoxFor(m => m.Address, new { @class = "form-control" }) </div> </div> 

然后用新的属性更新AccountController上的Register()方法。

  // Add the Address properties: user.Address = model.Address; user.City = model.City; user.State = model.State; user.PostalCode = model.PostalCode;