Identity 2.0:创建自定义 ClaimsIdentity,例如:User.Identity.GetUserBy
本文关键字:Identity 例如 User GetUserBy 自定义 创建 ClaimsIdentity | 更新日期: 2023-09-27 18:35:41
请参阅类似的问题:需要在User.Identity中访问更多用户属性
我想创建自定义身份验证方法以与我的 Razor 视图一起使用,该方法允许轻松访问与 User.Identity 对象相关的IdentityUser
属性,但我不确定如何去做。我想创建几个类似于User.Identity.GetUserName()
、User.Identity.GetUserById()
等的自定义扩展......而不是使用此 ViewContextExtension 方法。我的身份验证类型当前是 VS2013 MVC5 模板中DefaultAuthenticationTypes.ApplicationCookie
的默认类型。如 Shoe 所述,我需要在用户登录后插入此声明。
我的问题是:
如何以及在何处创建在 IPrincipal 下具有 out 参数 this IIdentity
的自定义声明?
这将允许我通过 CookieAuthentication 在 DDD 设置中的实体视图中访问用户属性,其中我使用 Identity 2.0 在单个应用程序中有多个 DbContext。我最终将使用 WebAPI,但现在我想让它尽可能简单。我找到了这个SO问答,但它是针对使用票证的Web表单的。也不确定门票和代币之间的区别?
这是使用来自基本控制器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<int>());
//...
}
基本控制器.cs
public string GetAvatarUrlById(int id)
{
var user = UserManager.FindById(id);
return "../../" + user.ImageUrl;
}
扩展.cs
public static class ViewContextExtension
{
public static BaseController BaseController(this ViewContext view)
{
var baseController = (BaseController)view.Controller;
return baseController;
}
}
我正在寻找的是在哪里以及如何?
视图:
<img src="@User.Identity.GetAvatarUrl()" alt="User.Identity.GetAvatarUrl()" />
溶液
我只是编辑了 Extension.cs 文件,并对用于 _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
<img src="@User.Identity.GetPhoneNumber()" />
我实际上使用 LukeP 对这个 SO 问题的答案找到了解决方案,但正如 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视图中使用了@User.Id, @User.UserName, @User.AvatarUrl