4

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

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

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

ASP.Net 在这个 cookie 中放了什么?如果我的用户名格式已知(例如顺序编号),是否有可能有人可以轻松复制此 cookie 并将其放在自己的计算机上,从而能够以其他用户身份访问该站点?

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

对于这两点,我将不胜感激。我收集了第二个我可能会在 global.asax 中放一些东西来拦截身份验证?

提前致谢。

4

2 回答 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);
    }
于 2012-10-16T15:18:50.300 回答
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.) 另一种方法是保留一个通用的应用程序范围的通用 PageBase 类,该类继承自 System.Web.UI.Page 并充当所有 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)
    {

    }
}
于 2010-06-25T14:34:37.930 回答