如何在Asp.Net会员提供商中处理“记住我”

时间:2010-06-25 14:17:52

标签: asp.net cookies forms-authentication membership remember-me

我为ASP.Net网站编写了一个自定义成员资格提供程序。

我使用默认的Forms.Authentication重定向,您只需将true传递给方法,告诉当前用户“记住我”。

我认为这个函数只是将cookie写入包含用户的一些登录凭证的本地机器。

ASP.Net在这个cookie中放了什么?是否可以知道我的用户名格式(例如顺序编号),有人可以轻松复制这个cookie,并将其放在自己的机器上,能够以另一个用户身份访问该网站吗?

此外,我需要能够识别拥有cookie的用户的身份验证。由于他们最后一次登录他们的帐户可能已被取消,他们可能需要更改他们的密码等所以我需要截取身份验证的选项,如果一切仍然正常,允许他们继续或将他们重定向到正确的登录页面

我很乐意为这两点提供指导。我第二次收集我可以在global.asax中放一些东西拦截身份验证吗?

提前致谢。

2 个答案:

答案 0 :(得分:4)

对我而言,解决方案是区分浏览器会话身份验证cookie(不要与asp.net会话cookie混淆)和持久性之一 - 设置低到期将创建一个持久性cookie,这意味着当浏览器关闭并在到期时间内重新打开时,它会被记住。以下适用于我:

public void SetAuthenticationCookie(LoginView loginModel)
    {
      if (!loginModel.RememberMe)
      {
        FormsAuthentication.SetAuthCookie(loginModel.Email, false);
        return;
      }
      const int timeout = 2880; // Timeout is in minutes, 525600 = 365 days; 1 day = 1440.
      var ticket = new FormsAuthenticationTicket(loginModel.Email, loginModel.RememberMe, timeout);
      //ticket.
      string encrypted = FormsAuthentication.Encrypt(ticket);
      var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encrypted)
        {
          Expires = System.DateTime.Now.AddMinutes(timeout),
          HttpOnly = true
        };
      HttpContext.Current.Response.Cookies.Add(cookie);
    }

答案 1 :(得分:3)

FormsAuthentication和MembershipProviders是两个完全不同的东西,它们仍然可以很好地相互协作。如果您已经编写了持久性cookie [“记住我”],那么下次您只需调用Membership.GetUser(),它将返回当前登录用户的MembershipUser实例或null没有用户登录。

因此,当用户第一次到达并使用“记住我”进行身份验证时,您应该编写一个持久性cookie,如下所示。

FormsAuthentication.RedirectFromLoginPage(strUserName, true);

假设用户没有注销并离开网页并在一段时间后回来。您可以简单地调用MembershipUser.GetUser(),并检查用户是否已从FormsAuthentication写入的持久性cookie中记录。

MembershipUser someUser = Membership.GetUser();
if(someUser == null)
{
    FormsAuthentication.SignOut();
    FormsAuthentication.RedirectToLoginPage();
}
else
{
    //Take where logged in users go.
}

您可以在登录页面本身或主要登录页面上执行此操作,以拦截用户帐户以检查他是否需要更改密码或帐户是否已按照您的情况禁用。

修改

有两种方法可以做到这一点。

1。)在global.asax的Session_Start事件中检查上述验证,并设置在该特定会话的所有页面上可用的会话密钥。

2。)另一种方法是保留一个从System.Web.UI.Page继承的公共应用程序范围的常见PageBase类,并充当所有asp.net页面的基页类。在公共PageBase类的Page Load上检查上面提到的身份验证。在这种情况下,您必须仔细编写条件重定向,因为这可能会导致无限重定向而没有结束,因为它将在公共PageBase类的所有页面的Page_Load上运行。

public class PageBase : System.Web.UI.Page
{
    /// <summary>
    /// Initializes a new instance of the Page class.
    /// </summary>
    public Page()
    {
        this.Load += new EventHandler(this.Page_Load);
    }


    private void Page_Load(object sender, EventArgs e)
    {
        try
        {
            AuthenticateUser();
        }
        catch
        {
            //handle the situation gracefully.
        }
    }

    private AuthenticateUser()
    {
        MembershipUser someUser = Membership.GetUser();
        if(someUser == null)
        {
            FormsAuthentication.SignOut();
            FormsAuthentication.RedirectToLoginPage();
        }
        else
        {
            //Take where logged in users go.
        }
    }
}

//in your asp.net page code-behind

public partial class contact : PageBase
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }
}