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

Identity 2.0:创建自定义 ClaimsIdentity,例如:User.Identity.GetUserBy

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

相关文章: