Identity 2.0:创建自定义ClaimsIdentity例如:User.Identity.GetUserById (int id)for Per Request Validation

请参阅此类似问题: 需要在User.Identity中访问更多用户属性

我想创建自定义身份validation方法以与我的Razor Views一起使用,这样可以轻松访问与User.Identity对象关联的IdentityUser属性,但我不知道如何去做。 我想创建几个类似于User.Identity.GetUserName()User.Identity.GetUserById()等的自定义扩展…而不是使用此ViewContextExtension方法。 我的身份validation类型当前是VS2013 MVC5模板的默认类型DefaultAuthenticationTypes.ApplicationCookie 。 正如Shoe所说,我需要在用户登录后插入此声明。

我的问题是:

如何以及在何处创建一个在IPrincipal下具有this IIdentity的out参数的自定义声明?

这将允许我通过CookieAuthentication在DDD设置中的实体的ViewAuthentication中访问用户属性,其中我在使用Identity 2.0的单个应用程序中有多个DbContexts。 我最终将使用WebAPI,但是现在我希望尽可能简单。 我已经找到了这个SO Q&A但是它适用于使用Tickets的Web Forms。 不确定门票和代币之间的区别吗?

这是使用基本控制器中的ViewContext的当前方法:

视图:

  @using Microsoft.AspNet.Identity @using Globals.Helpers @using Identity //custom Identity for Domain @using Microsoft.AspNet.Identity.Owin @if (Request.IsAuthenticated) { var url = @ViewContext.BaseController().GetAvatarUrlById(User.Identity.GetUserId()); //... } 

BaseController.cs

  public string GetAvatarUrlById(int id) { var user = UserManager.FindById(id); return "../../" + user.ImageUrl; } 

Extensions.cs

  public static class ViewContextExtension { public static BaseController BaseController(this ViewContext view) { var baseController = (BaseController)view.Controller; return baseController; } } 

我在寻找的是在哪里以及如何?

视图:

 User.Identity.GetAvatarUrl() 

我只是编辑了Extension.cs文件并使用了inheritance用于Base控制器,该控制器用于_LoginPartial.cshtml并编辑了ViewContextExtension类:

 #region ViewContextExt public static class ViewContextExtension { public static BaseController BaseController(this ViewContext view) { var baseController = (BaseController)view.Controller; return baseController; } public static string GetAvatarUrl(this IIdentity identity) { return ((ClaimsIdentity)identity).Claims.First(c => c.Type == "AvatarUrl").Value; } } 

}

endregion

MVC中的IIdentity对象将是与用户身份相对应的已颁发令牌。 这与您在代表用户的后端(例如User类)上使用的任何对象或方法不同。 如果您想使用用户的身份来获取自定义值,那么您需要在登录时(或在其他某个时间点)将其放入其声明对象(即身份令牌)中。

您可以通过向用户提供身份来随时添加声明。

 AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie); var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie); identity.AddClaim(new Claim("PhoneNumber", "123-456-7890")); AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity); 

当您将该声明插入其令牌时,您可以使用此类扩展方法检索它…

 public static string GetPhoneNumber(this IIdentity identity) { return ((ClaimsIdentity)identity).FindFirstValue("PhoneNumber"); } 

剃刀

 @using MyProject.Web.Extensions  

我实际上是通过LukeP使用这个问题的答案找到了解决方案,但正如Shoe所说,这是MVC5之前的版本,我们可以简单地提出一个声明。

我做了以下改动:

  interface IDomainPrincipal : IPrincipal { int Id { get; set; } string UserName { get; set; } string AvatarUrl { get; set; } } public class DomainPrincipal : IDomainPrincipal { public IIdentity Identity { get; private set; } public bool IsInRole(string role) { return false; } public DomainPrincipal(string email) { this.Identity = new GenericIdentity(email); } public int Id { get; set; } public string UserName { get; set; } public string AvatarUrl { get; set; } } 

然后我分别在我的@Razor Views中使用了@User.Id, @User.UserName, @User.AvatarUrl