在Windows+Forms登录中保持我的登录状态

3
我希望在我的ASP.NET应用程序中实现Facebook和GMail的功能。
我使用了Windows和Forms登录的组合,并且一切都运行正常。
我有一个登录页面,其中包含以下代码:
    public const int LOGON32_LOGON_INTERACTIVE = 2;
    public const int LOGON32_PROVIDER_DEFAULT = 0;

    IntPtr token;
    IntPtr tokenDuplicate;

    [DllImport("advapi32.dll", SetLastError = true)]
    public static extern int LogonUserA(String lpszUserName,
        String lpszDomain,
        String lpszPassword,
        int dwLogonType,
        int dwLogonProvider,
        ref IntPtr phToken);
    [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern int DuplicateToken(IntPtr hToken,
        int impersonationLevel,
        ref IntPtr hNewToken);

    [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern bool RevertToSelf();

    [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
    public static extern bool CloseHandle(IntPtr handle);


protected void LoginButton_Click(object sender, EventArgs e)
        {
 if (LogonUserA(userName, Domain.Text, Password.Text, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref token) == 0)
            {
                BadCredentials.Visible = true;
                BadCredentials.Text = "Not A Valid User";
                Global.logger.Info("LogonUserA failed with GetLastWin32Error code =" + Marshal.GetLastWin32Error());
                return;
            }
            Global.logger.Info("LogonUserA is sucessful");


                if (DuplicateToken(token, 2, ref tokenDuplicate) == 0)
                {
                    BadCredentials.Visible = true;
                    BadCredentials.Text = "Internal Error: DuplicateToken failed";
                    return;
                }

Session["TokenDuplicate"] = tokenDuplicate;
            if (new GUIUtility().impersonateValidUser(Session) == false)
            {
                BadCredentials.Visible = true;
                BadCredentials.Text = "Impersonation failed";
                return;
            }

if (GUIUtility.IsUserPartOfWindowsGroup(compUsrNameForEncryption, adminGroupName) == true)
            {
                // The user is Instance Admin

                BadCredentials.Visible = false;


            }
// Create the authentication ticket
        FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(1,                          // version
                                       UserName.Text,           // user name
                                       DateTime.Now,               // creation
                                       DateTime.Now.AddMinutes(60),// Expiration
                                       false,                      // Persistent 
                                       role);         // User data

        // Now encrypt the ticket.
        string encryptedTicket = FormsAuthentication.Encrypt(authTicket);

        // Create a cookie and add the encrypted ticket to the
        // cookie as data.
        HttpCookie authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);            

        //authCookie.Secure = FormsAuthentication.RequireSSL;

        // Add the cookie to the outgoing cookies collection.
        HttpContext.Current.Response.Cookies.Add(authCookie);
        //Response.Redirect(FormsAuthentication.GetRedirectUrl(UserName.Text, false));
        Response.Redirect("~/Default.aspx");
        // Company Admin has logged on

}

这是我的web.config文件中的内容,可能会有所帮助:

<authentication mode="Forms">
        <forms loginUrl="Login.aspx" defaultUrl="~/Default.aspx" name="GUI" slidingExpiration="true" timeout="30" path="/">
        </forms>
    </authentication>
    <authorization>
        <deny users="?"/>
        <allow users="*"/>
    </authorization>

<sessionState mode="InProc" cookieless="false" timeout="30"/>

    <!--
        The <customErrors> section enables configuration 
        of what to do if/when an unhandled error occurs 
        during the execution of a request. Specifically, 
        it enables developers to configure html error pages 
        to be displayed in place of a error stack trace.
  -->
    <customErrors mode="On" defaultRedirect="~/Login.aspx">
        <error statusCode="403" redirect="NoAccess.htm" />
        <error statusCode="404" redirect="FileNotFound.htm" />
    </customErrors>

这是我 global.ascx 中的代码:

 protected void Application_BeginRequest(object sender, EventArgs e)
    {

        try
        {
            string cookieName = FormsAuthentication.FormsCookieName.ToString();
            HttpCookie authCookie = Context.Request.Cookies[cookieName];
            if (null != authCookie)
            {
                authCookie.Secure = true;
            }
        }
        catch (Exception ex)
        {
            Global.logger.Error("Application_BeginRequest: Exception: " + ex);
        }
    }

     protected void Application_AuthenticateRequest(object sender, EventArgs e)
     {
        // Extract the forms authentication cookie

        string redirectSecureUrl = Request.Url.ToString();

        string cookieName = FormsAuthentication.FormsCookieName.ToString();
        HttpCookie authCookie = Context.Request.Cookies[cookieName];


        if (null == authCookie)
        {

            // There is no authentication cookie.
            return;
        }

        FormsAuthenticationTicket authTicket = null;
        try
        {
            authTicket = FormsAuthentication.Decrypt(authCookie.Value);
        }
        catch (Exception ex)
        {
            Global.logger.Error("Application_AuthenticateRequest: Exception: " + ex);

            return;
        }

        if (null == authTicket)
        {
            // Cookie failed to decrypt.
            return;
        }

        // When the ticket was created, the UserData property was assigned a
        // pipe delimited string of role names.
        string[] roles = authTicket.UserData.Split(new char[] { '|' });

        // Create an Identity object
        FormsIdentity id = new FormsIdentity(authTicket);

        // This principal will flow throughout the request.
        GenericPrincipal principal = new GenericPrincipal(id, roles);
        // Attach the new principal object to the current HttpContext object
        Context.User = principal;
    }

如果将持久化cookie属性设置为true,会发生什么?

谢谢。


我尝试将其更改为false,但行为仍然没有变化。当打开登录页面并登录一次,然后打开该浏览器的新窗口并尝试打开网站时,我不需要再次登录。但是当我关闭所有窗口并再次打开应用程序时,我会回到登录界面。 - user175084
所以,我希望它能够在不要求用户重新登录的情况下继续记录,除非我按下“退出登录”按钮。 - user175084
1
你似乎在做很多框架本来可以为你完成的工作。将cookie设置为持久性,它就不再是仅会话使用的,而是会持续一段时间,无论你是否打开或关闭浏览器。 - Simon Halsey
@Simon,为什么不把它发布为答案而不是评论,这样他们就可以将其标记为正确答案(如果确实如此)。 - Since_2008
1个回答

1

参考...

如果您使用 true,则会创建一个具有固定到期日期的 cookie,而不是仅限会话的 cookie。Cookie 和验证票证将在关闭浏览器后继续存在。

西蒙


你能给我指一个例子或一些参考资料吗?这将非常有帮助。 - user175084
创建持久化Cookie的.NET参考 -> http://msdn.microsoft.com/zh-cn/library/ka5ffkce(v=VS.90).aspx - Simon Halsey

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