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

发布于 2024-09-07 04:59:32 字数 459 浏览 1 评论 0原文

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

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

我认为这个函数只是将一个 cookie 写入本地计算机,其中包含用户的一些登录凭据。

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

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

我将非常感谢您对这两点的指导。我想知道我是否可以在 global.asax 中放入一些内容来拦截身份验证?

提前致谢。

Ive written a custom membership provider for my ASP.Net website.

Im using the default Forms.Authentication redirect where you simply pass true to the method to tell it to "Remember me" for the current user.

I presume that this function simply writes a cookie to the local machine containing some login credential of the user.

What does ASP.Net put in this cookie? Is it possible if the format of my usernames was known (e.g. sequential numbering) someone could easily copy this cookie and by putting it on their own machine be able to access the site as another user?

Additionally I need to be able to inercept the authentication of the user who has the cookie. Since the last time they logged in their account may have been cancelled, they may need to change their password etc so I need the option to intercept the authentication and if everything is still ok allow them to continue or to redirect them to the proper login page.

I would be greatful for guidance on both of these two points. I gather for the second I can possibly put something in global.asax to intercept the authentication?

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

昔梦 2024-09-14 04:59:32

对我来说,解决方案是区分浏览器会话身份验证 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);
    }

For me the solution was differentiating between a browser-session auth cookie (not to be confused with the asp.net session cookie) and a persistent one - setting a low expiration will create a persistent cookie meaning it gets remembered when the browser is closed and re-opened within the expiration time. The following works for me:

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);
    }
盛装女皇 2024-09-14 04:59:32

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 类的页面加载上检查身份验证,如上所述。在这种情况下,您必须仔细编写条件重定向,因为这可能会导致无限重定向,因为它将在公共 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)
    {

    }
}

FormsAuthentication and MembershipProviders are two completely different things, still they are made to work with each other very well. If you have written a persistent cookie ["Remember Me"] then next time, you can simply call Membership.GetUser() which will return you the MembershipUser instance of the currently logged in user or null if no user is logged in.

So first time when user arrives and authenticates with "Remember Me", you shall write a persistent cookie as following.

FormsAuthentication.RedirectFromLoginPage(strUserName, true);

Assuming user does not logout and leaves webpage and comes back after sometime. You can simply call MembershipUser.GetUser() as following and check if the user is already logged from the persistent cookie written by FormsAuthentication.

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

You can do this check on your Login page itself or main landing page to intercept the User account to check if he needs to change the password or if the account is disabled as in your case.

EDIT

There are two ways to do this.

1.) Check for authentication as mentioned above in Session_Start event in global.asax and set a session key that becomes available on all pages for that particular session.

2.) Another way is too keep a common application wide common PageBase class that inherits from System.Web.UI.Page and acts as base page class for all your asp.net pages. On the Page Load of the common PageBase class check for the authentication as mentioned above. You will have to carefully write conditional redirection in this case since this might head towards infinite redirection with no end since it will run on Page_Load of all page from the common PageBase class.

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)
    {

    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文