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

yar*_*lty 4 c# class-extensions asp.net-mvc-5 razor-3 asp.net-identity-2

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

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

我的问题是:

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

这将允许我通过CookieAuthentication在DDD设置中的实体的View中访问用户属性,其中我在使用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<int>());

        //...
    }
Run Code Online (Sandbox Code Playgroud)

BaseController.cs

        public string GetAvatarUrlById(int id)
        {

            var user = UserManager.FindById(id);

            return "../../" + user.ImageUrl;
        }
Run Code Online (Sandbox Code Playgroud)

Extensions.cs

    public static class ViewContextExtension
    {
        public static BaseController BaseController(this ViewContext view)
        {
            var baseController = (BaseController)view.Controller;
            return baseController;
        }
    }
Run Code Online (Sandbox Code Playgroud)

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

视图:

<img src="@User.Identity.GetAvatarUrl()" alt="User.Identity.GetAvatarUrl()" />
Run Code Online (Sandbox Code Playgroud)

我只是编辑了Extension.cs文件并使用了继承用于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;
    }
}
Run Code Online (Sandbox Code Playgroud)

}

endregion

Sho*_*hoe 13

IIdentityMVC中的对象将是与用户身份相对应的已颁发令牌.这与您在后端使用的代表用户(比如一个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);
Run Code Online (Sandbox Code Playgroud)

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

public static string GetPhoneNumber(this IIdentity identity)
{
    return ((ClaimsIdentity)identity).FindFirstValue("PhoneNumber");
}
Run Code Online (Sandbox Code Playgroud)

剃刀

@using MyProject.Web.Extensions

<img src="@User.Identity.GetPhoneNumber()" />
Run Code Online (Sandbox Code Playgroud)

  • 如果你想重定向匿名用户,你应该在控制器级别进行,虽然正确放置的`Authorize`属性通常更好,除非它是一个匿名和经过身份验证的用户都可以查看的页面.您不必根据身份检查模型的ID,因为它们应该相同.我的观点是用户的身份(User.Identity)是一个不同的对象,具有与`User`类不同的属性,你不能简单地抓住`User`属性而不先将它们放入Identity对象(通过索赔). (3认同)