加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-mvc-5 – 使用FormsAuthenticationTicket的MVC Identity

发布时间:2020-12-15 22:34:08 所属栏目:asp.Net 来源:网络整理
导读:我正在用自定义版本替换(HttpContext.Current.User)IPrincipal,以便我可以存储更多信息登录和用户.我在使用FormsAuthtenticationTicket之前已完成此操作,但其他方式基于Memberhipship和SimpleMembership提供程序. 我的问题是,我可以使用FormsAuthenticationT
我正在用自定义版本替换(HttpContext.Current.User)IPrincipal,以便我可以存储更多信息登录和用户.我在使用FormsAuthtenticationTicket之前已完成此操作,但其他方式基于Memberhipship和SimpleMembership提供程序.

我的问题是,我可以使用FormsAuthenticationTicket存储我的ICustomPrincipal的cookie,它会干扰或破坏OWIN Identity Pipline吗?我觉得我会混合苹果和橘子.

示例保存:

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;
    }
}

编辑
我有这个用于创建声明

public ClaimsIdentity CreateIdentity(
             LoginAttempt loginAttempt)
        {
            UserProfile userProfile = GetUserProfile(loginAttempt.UserName);

            var applicationUser = FindById(userProfile.AspNetUserId);

            ClaimsIdentity identity;
            try
            {
                 identity = UserManager.CreateIdentity(applicationUser,DefaultAuthenticationTypes.ApplicationCookie);
            }
            catch (Exception ex)
            {
                _log.Error(ex.Message,ex);
                return null;
            }
            //UserManager.GetClaims()
            identity.AddClaim(new Claim("LoginAttemptId",loginAttempt.LoginAttemptId.ToString(),ClaimValueTypes.String));
            identity.AddClaim(new Claim("UserProfileId",loginAttempt.UserProfileId.ToString(),ClaimValueTypes.String));
            identity.AddClaim(new Claim("SubscriptionType",userProfile.SubscriptionType,ClaimValueTypes.String));

            IList<string> roles= UserManager.GetRoles(applicationUser.Id);

            identity.AddClaim(new Claim(ClaimTypes.Role,roles.First()));
            return identity;
        }

这用于提取

public static long GetLoginAttemptId(this IIdentity principal)
        {
            var claimsPrincipal = principal as ClaimsIdentity;
            if (claimsPrincipal == null)
            {
                //throw new Exception("User is not logged in!");
                return -1;
            }
            var nameClaim = claimsPrincipal.Claims.FirstOrDefault(c => c.Type == "LoginAttemptId");
            if (nameClaim != null)
            {
                return Convert.ToInt64( nameClaim.Value);// as long;
            }

            return -1;
        }

编辑
这些是我得到的主张.我已经注销并重新登录.

解决方法

声称具有完全相同的目的.实际上只有新的API才是这样的.

声明基本上是一个字典< String,String>它存储在auth-cookie中,可通过IPrincipal获得.但是你不需要做ICustomPrincipal,因为你在IPrincipal背后的实际对象是ClaimsPrincipal并且有一个声明列表.

您只需在登录前向Idnentity对象添加额外信息:

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;
}

我已经在一些项目中成功使用了这种方法.有关更多代码示例,请参见other similar answers.
这是another article,虽然我不鼓励在MVC应用程序中使用Thread.CurrentPrincipal或ClaimsPrincipal.Current – 你并不总是得到你所期望的,特别是当用户没有登录或在AppPool启动的早期阶段.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读