如何在Asp.Net Membership Provider中处理“记住我”功能

4
我为我的ASP.Net网站编写了一个自定义成员资格提供程序。
我正在使用默认的Forms.Authentication重定向,其中您只需将true传递给该方法即可告诉它为当前用户“记住我”。
我认为这个函数只是在本地计算机上写入一个包含用户登录凭据的cookie。
ASP.Net在这个cookie中放了什么?如果我的用户名格式已知(例如顺序编号),是否有可能有人可以轻松复制此cookie,并通过将其放在自己的计算机上以另一个用户的身份访问该站点?
此外,我需要能够拦截具有cookie的用户的身份验证。由于他们上次登录以来,他们的帐户可能已被取消,他们可能需要更改密码等,因此我需要选择拦截身份验证,如果一切仍然正常,则允许他们继续或将其重定向到适当的登录页面。
我将非常感谢关于这两个问题的指导。我收集到的信息是,对于第二个问题,我可能可以在global.asax中放置一些内容来拦截身份验证?
提前致谢。
2个回答

4

对我而言,解决方案是区分浏览器会话验证cookie(与asp.net会话cookie不同)和持久性验证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);
    }

3
FormsAuthentication和MembershipProviders是两个完全不同的东西,但它们被设计成能够很好地配合使用。如果你已经写了一个持久化Cookie("Remember Me"),那么下次,你可以简单地调用Membership.GetUser(),这将返回当前登录用户的MembershipUser实例,如果没有用户登录,则返回null
因此,当用户第一次到达并使用“Remember Me”进行验证时,您应该按照以下方式编写一个持久的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.)另一种方法是保持一个通用应用程序范围的PageBase类,该类继承自System.Web.UI.Page并作为所有asp.net页面的基本页面类。在通用PageBase类的Page Load中检查身份验证,如上所述。在这种情况下,您将需要仔细编写条件重定向,因为它会在所有页面的Page_Load上运行从通用PageBase类开始,可能会导致无尽的重定向而无法结束。
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)
    {

    }
}

感谢您的回复。当用户返回应用程序时,他们可以着陆在任何页面上,因此我需要一种全局处理方式。然后我可以检查帐户是否仍处于活动状态等等。 - Remotec

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接