代码之家  ›  专栏  ›  技术社区  ›  Remotec

如何在Asp.Net成员资格提供程序中处理“记住我”

  •  4
  • Remotec  · 技术社区  · 14 年前

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

    我使用默认表单。身份验证重定向,你只需将true传递给方法,告诉它为当前用户“记住我”。

    ASP.Net在这个cookie中放了什么?如果我的用户名的格式是已知的(例如顺序编号),有人可以很容易地复制这个cookie,并且通过将它放在自己的机器上,就可以以另一个用户的身份访问这个站点吗?

    另外,我还需要能够接受拥有cookie的用户的身份验证。由于他们上次登录的帐户可能已被取消,他们可能需要更改密码等,因此我需要选择拦截身份验证,如果一切正常,允许他们继续或重定向到正确的登录页面。

    我很乐意在这两点上得到指导。我想我可以在global.asax中放点东西来拦截身份验证?

    2 回复  |  直到 14 年前
        1
  •  4
  •   jenson-button-event    8 年前

    对我来说,解决办法是 浏览器会话 持久的 设置低过期时间 将创建一个持久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);
        }
    
        2
  •  3
  •   this. __curious_geek    14 年前

    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 event中检查上述身份验证,并设置在该特定会话的所有页面上都可用的会话密钥。

    2.)另一种方法是保留一个继承自System.Web.UI.Page的通用应用程序范围的公共页面基类,并充当所有asp.net页面的基类。在公共PageBase类的页面加载中,检查上面提到的身份验证。在这种情况下,您必须小心地编写条件重定向,因为这可能会走向无限重定向而没有结束,因为它将在从公共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)
        {
    
        }
    }