简体   繁体   English

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

[英]How to handle “Remember me” in the Asp.Net Membership Provider

Ive written a custom membership provider for my ASP.Net website. 我已经为我的ASP.Net网站编写了自定义成员资格提供程序。

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. 我使用默认的Forms.Authentication重定向,您只需将true传递给方法即可告诉当前用户“记住我”。

I presume that this function simply writes a cookie to the local machine containing some login credential of the user. 我认为该函数只是将cookie写入包含用户登录凭据的本地计算机。

What does ASP.Net put in this cookie? ASP.Net在此cookie中放置了什么? Is it possible if the format of my usernames was known (eg 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? 如果知道我的用户名格式(例如,顺序编号),是否有人可以轻松地复制此cookie,并将其放在自己的计算机上就可以作为另一个用户访问该网站?

Additionally I need to be able to inercept the authentication of the user who has the cookie. 另外,我需要能够感知具有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? 我收集第二秒钟,我可能可以在global.asax中添加一些内容以拦截身份验证?

Thanks in advance. 提前致谢。

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. 对我来说,解决方案是区分浏览器会话身份验证cookie(不要与asp.net会话cookie混淆)和持久性 cookie- 设置较低的到期时间将创建持久性cookie,这意味着在关闭浏览器时会记住该cookie。在有效期内重新打开。 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);
    }

FormsAuthentication and MembershipProviders are two completely different things, still they are made to work with each other very well. FormsAuthentication和MembershipProviders是两个完全不同的东西,但它们仍然可以很好地相互配合。 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. 如果您编写了一个持久性cookie [“ Remember Me”],则下次可以简单地调用Membership.GetUser() ,它将返回您当前登录用户的MembershipUser实例;如果没有用户登录,则返回null

So first time when user arrives and authenticates with "Remember Me", you shall write a persistent cookie as following. 因此,当用户首次到达并通过“记住我”进行身份验证时,您应按以下方式编写持久性cookie。

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.GetUser()并检查用户是否已经从FormsAuthentication编写的持久cookie中登录。

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. 1.)如上所述,在global.asax的Session_Start事件中检查身份验证,并设置一个会话密钥,该密钥在该特定会话的所有页面上都可用。

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. 2.)另一种方法是保留从System.Web.UI.Page继承并用作所有asp.net页的基页类的通用应用程序范围内的通用PageBase类。 On the Page Load of the common PageBase class check for the authentication as mentioned above. 如上所述,在公共PageBase类的Page Load中检查身份验证。 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. 在这种情况下,您将必须仔细地编写条件重定向,因为这可能会朝着无限重定向前进,因为它将在通用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)
    {

    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM