Asp.net mvc 5 使用FormsAuthenticationTicket的MVC标识2

Asp.net mvc 5 使用FormsAuthenticationTicket的MVC标识2,asp.net-mvc-5,forms-authentication,asp.net-identity-2,Asp.net Mvc 5,Forms Authentication,Asp.net Identity 2,我正在用自定义版本替换(HttpContext.Current.User)IPrincipal,以便存储登录和用户的更多信息。在使用FormsAttenticationTicket之前,我已经这样做了,但是其他的方法都是基于Membership和SimpleMembership提供者的 我的问题是,我是否可以使用FormsAuthenticationTicket来存储我的ICustomPrincipal的cookie,因为它会干扰或破坏OWIN身份管道?我觉得我会把苹果和桔子混合在一起 保存示例

我正在用自定义版本替换(HttpContext.Current.User)IPrincipal,以便存储登录和用户的更多信息。在使用FormsAttenticationTicket之前,我已经这样做了,但是其他的方法都是基于Membership和SimpleMembership提供者的

我的问题是,我是否可以使用FormsAuthenticationTicket来存储我的ICustomPrincipal的cookie,因为它会干扰或破坏OWIN身份管道?我觉得我会把苹果和桔子混合在一起

保存示例:

var user = userRepository.Users.Where(u => u.Email == viewModel.Email).First();

    CustomPrincipalSerializeModel serializeModel = new CustomPrincipalSerializeModel();
    serializeModel.UserId = user.Id;
    serializeModel.FirstName = user.FirstName;
    serializeModel.LastName = user.LastName;

    JavaScriptSerializer serializer = new JavaScriptSerializer();

    string userData = serializer.Serialize(serializeModel);

    FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(
             1,
             viewModel.Email,
             DateTime.Now,
             DateTime.Now.AddMinutes(15),
             false,
             userData);

    string encTicket = FormsAuthentication.Encrypt(authTicket);
    HttpCookie faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);
    Response.Cookies.Add(faCookie);
示例检索:

protected void Application_PostAuthenticateRequest(Object sender, EventArgs e)
{
    HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];

    if (authCookie != null)
    {
        FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);

        JavaScriptSerializer serializer = new JavaScriptSerializer();

        CustomPrincipalSerializeModel serializeModel = serializer.Deserialize<CustomPrincipalSerializeModel>(authTicket.UserData);

        CustomPrincipal newUser = new CustomPrincipal(authTicket.Name);
        newUser.UserId = serializeModel.UserId;
        newUser.FirstName = serializeModel.FirstName;
        newUser.LastName = serializeModel.LastName;

        HttpContext.Current.User = newUser;
    }
}
编辑 这些是我得到的索赔。我已注销并重新登录。

有些主张的目的完全相同。只有新的API实际上是这样设计的

声明基本上是一个
字典
,存储在auth cookie中,可通过
IPrincipal
获得。但是您不需要执行
ICustomPrincipal
,因为您在
ipprincipal
后面得到的实际对象是
ClaimsPrincipal
,并且有一个声明列表

您应该在登录之前向IDElenty对象添加额外信息:

public async override Task CreateIdentityAsync(ApplicationUser applicationUser)
{
    var identity = await base.CreateIdentityAsync(applicationUser, DefaultAuthenticationTypes.ApplicationCookie);

    identity.AddClaim(new Claim("MyApp:FullName", applicationUser.FullName));
    return identity;
}
然后,您可以通过扩展从IPrincipal获取这些数据:

public static String GetFullName(this IPrincipal principal)
{
    var claimsPrincipal = principal as ClaimsPrincipal;
    if (claimsPrincipal == null)
    {
         throw new Exception("User is not logged in!");
    }
    var nameClaim = principal.Claims.FirstOrDefault(c => c.Type == "MyApp:FullName");
    if (nameClaim != null)
    {
        return nameClaim.Value;
    }

    return String.Empty;
}
我已经在一些项目中成功地使用了这种方法。有关更多代码示例,请参阅。

尽管我不鼓励在MVC应用程序中使用
Thread.CurrentPrincipal
ClaimsPrincipal.Current
,但您并不总能得到您期望的结果,尤其是当用户未登录或处于AppPool启动的早期阶段时。

这种方法对我有效(使用MVC4),与上述方法略有不同

public class ApplicationUser : IdentityUser
{
    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
    {
        // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        // Add custom user claims here
        userIdentity.AddClaim(new Claim("MyApp:OrganizationId", OrganizationID.ToString()));

        return userIdentity;
    }

    public int OrganizationID { get; set; }
}
然后,我在控制器中使用如下扩展方法:

var organizationId = User.Identity.GetOrganizationId();

希望这对某人有用。

我无法获得wrkHow的分机,所以?出什么问题了?对不起,我弄明白了。谢谢你的回答。当我添加一个具有已知类型“ClaimTypes.Role”的声明时,上面的解决方案运行良好,但当我添加一个自定义字符串,即.MyApp:LoginAttentid时,它没有找到声明。请小心预定义类型-它们可能被系统使用,并且可能会干扰系统数据。所有用户角色都作为类型为
ClaimTypes.Role
的声明添加,如果您在此声明中添加更多信息,您将为此用户提供一个名为“Joe Bloggs”的角色。
public class ApplicationUser : IdentityUser
{
    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
    {
        // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        // Add custom user claims here
        userIdentity.AddClaim(new Claim("MyApp:OrganizationId", OrganizationID.ToString()));

        return userIdentity;
    }

    public int OrganizationID { get; set; }
}
public static class IdentityExtensions
    {
        public static int GetOrganizationId(this IIdentity principal)
        {
            var claimsPrincipal = principal as ClaimsIdentity;
            if (claimsPrincipal == null)
            {
                throw new Exception("User is not logged in!");
            }

            var nameClaim = claimsPrincipal.Claims.FirstOrDefault(c => c.Type == "MyApp:OrganizationId");
            if (nameClaim != null)
            {
                return int.Parse(nameClaim.Value);
            }

            throw new Exception("ID doesn't exists");
        }
    }
var organizationId = User.Identity.GetOrganizationId();