6

看到这个类似的问题:Need access more user properties in User.Identity

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

我的问题是:

您如何以及在何处创建具有this IIdentityIPrincipal 下的 out 参数的自定义声明?

这将允许我通过视图中的 CookieAuthentication 访问用户属性,以访问 DDD 设置中的实体,其中我在使用 Identity 2.0 的单个应用程序中有多个 DbContext。我最终将使用 WebAPI,但现在我希望它尽可能简单。我找到了这个 SO Q&A,但它适用于使用门票的 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 的 Base 控制器的继承并编辑了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
4

2 回答 2

13

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()" />
于 2014-12-29T19:08:45.147 回答
1

实际上,我使用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; }
    }

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

于 2015-01-15T02:03:11.730 回答