c# - FromsAuthenticationTicket.UserData 始终为空并且身份验证 cookie 不保留值

标签 c# asp.net-mvc cookies forms-authentication

我在登录中有以下代码(用户名,密码)

if (hasher.Compare(password, person.Hash))
                {
                    FormsAuthentication.SetAuthCookie(userId, true);
                    OpenAccount(person);

                    var principle = new GenericPrincipal( new GenericIdentity($"{person.FirstName} {person.LastName}"), new string[] {"All"});
                    var data = Konstants.Serialize(principle);
                    var ticket = new FormsAuthenticationTicket(1, principle.Identity.Name, DateTime.Now, DateTime.Now.AddMinutes(30), true, data);
                    var encryptedTicket = FormsAuthentication.Encrypt(ticket);


                    FormsAuthentication.SetAuthCookie(principle.Identity.Name, false);
                    var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
                    Response.SetCookie(cookie);
                    Response.RedirectToRoute("Default");
                }

然后在 Global.asax 中我有以下代码:

protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
    var  authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
    try
    {
        if (authCookie != null)
        {
            FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(authCookie.Value);
            if (!string.IsNullOrEmpty(ticket.UserData))
            {
                var principle = Konstants.Deserialize<GenericPrincipal>(ticket.UserData);
                HttpContext.Current.User = principle;
            }
        }
    }
    catch 
    {


    }
}

但在 AutheticateRequest 中,ticket.UserData 始终为空。事实上,我得到的 cookie 值是身份验证之前的值,而不是我存储的值。我在这里做错了什么。

更新:序列化和反序列化代码如下:

   public static string Serialize<T>(T obj)
    {
        var ret = string.Empty;
        using(var ms = new MemoryStream())
        {
            var bf = new BinaryFormatter();
            bf.Serialize(ms, obj);
            ret= Convert.ToBase64String(ms.GetBuffer());
        }
        return ret;
    }

public static T Deserialize<T>(string text)
{
    var obj = default(T);
    var data = Convert.FromBase64String(text);
    using(var ms = new MemoryStream(data, false))
    {
        var bf = new BinaryFormatter();
        obj = (T)bf.Deserialize(ms);
    }
    return obj;
}

最佳答案

在第一个代码块中您有两次对 SetAuthCookie 的调用,但如果您要创建自定义票证,则不需要这两次调用。我认为这应该可以解决问题:

OpenAccount(person);

var principle = new GenericPrincipal( new GenericIdentity($"{person.FirstName} {person.LastName}"), new string[] {"All"});
var data = Konstants.Serialize(principle);
var ticket = new FormsAuthenticationTicket(1, principle.Identity.Name, DateTime.Now, DateTime.Now.AddMinutes(30), true, data);
var encryptedTicket = FormsAuthentication.Encrypt(ticket);

var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
Response.SetCookie(cookie);
Response.RedirectToRoute("Default");

编辑:我还刚刚注意到您没有将序列化数据传递到新票证的 userData 字段中,这是故意的吗?

关于c# - FromsAuthenticationTicket.UserData 始终为空并且身份验证 cookie 不保留值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44589224/

相关文章:

c# - 共享内存和运行可执行文件的多个副本

asp.net-mvc - ASP.NET 用户未发布到 Azure

iOS UIWebView 和 Cookies 存储

asp.net-mvc - asp.net mvc模型数据库变更

python - 使用 AngularJS 在 Tornado 中进行 csrf 检查

authentication - 在 nginx 上使用一次性 cookie 进行非常简单的身份验证

c# - 如何使用 C# 中的 Azure.Storage.Blobs 从 Azure 存储 blob 获取 ByteArray 格式的文件

c# - 在 .net (c#) 中检查重新分析点的最佳方法是什么?

c# - Azure 媒体服务定位器

html - 创建表单时,字段集是否是一个可行的选择?