代码之家  ›  专栏  ›  技术社区  ›  Tom Halladay Amy B

使用ASP.Net成员身份使用户登录持久化

  •  17
  • Tom Halladay Amy B  · 技术社区  · 17 年前

    我有一个网站,是建立在ASP.NET3.5&SQL Server 2005,使用SQL成员资格提供程序,并可能形成身份验证。

    由于我的站点上的安全需求非常低,我想验证一次,然后无限期地保持登录(而不给用户选择权)。

    发生的情况是,用户登录并保持会话登录状态,然后在下次到达时注销。

     Try
                If Membership.ValidateUser(UserName.Text, Password.Text) Then
                    Security.UserManager.AuthenticateUser(UserName.Text)
    
                    If FormsAuthentication.GetRedirectUrl(UserName.Text, False) = "/default.aspx" Then
                        Try
                            'Custom Logic'
                        Catch Ex As Exception
                            'Custom Error handling'
                        End Try
                    Else
                        FormsAuthentication.RedirectFromLoginPage(UserName.Text, True)
                    End If
                End If
            Catch ex As Exception
                RaiseEvent ExceptionThrown(New ApplicationException("An error occurred trying to log the user in after account creation.", ex))
            End Try
    
    Public Shared Sub AuthenticateUser(ByVal Username As String)
        Dim Expiration As DateTime = DateTime.Now.AddMonths(3)
    
        Dim authTicket As FormsAuthenticationTicket = New FormsAuthenticationTicket(Username, True, Expiration.Subtract(Expiration).TotalMinutes)
        Dim EncryptedTicket As String = FormsAuthentication.Encrypt(authTicket)
        Dim AuthCookie As New HttpCookie(FormsAuthentication.FormsCookieName, EncryptedTicket)
        AuthCookie.Expires = Expiration
        HttpContext.Current.Response.Cookies.Add(AuthCookie)
    End Sub
    

    Web配置:

    <membership defaultProvider="SqlProvider" userIsOnlineTimeWindow="15">
       <providers>
          <clear />
          <add
             name="SqlProvider"
             type="System.Web.Security.SqlMembershipProvider"
             connectionStringName="GlobalConnString"
             applicationName="/"
             enablePasswordRetrieval="false"
             enablePasswordReset="true"
             requiresQuestionAndAnswer="false"
             requiresUniqueEmail="true"
             passwordFormat="Hashed"
             minRequiredPasswordLength="5"
             minRequiredNonalphanumericCharacters="0"
          />
       </providers>
    </membership>
    
    
    <authentication mode="Forms">
        <forms timeout="1439200" name="SITENAME" loginUrl="/login.aspx" />
    </authentication>
    

    编辑:以下是客户端存储的cookie信息:

    Name    ASP.NET_SessionId
    Value   r4dz1555f1pdne45n1zrlkmg
    Host    SITEADDRESS.com
    Path    /
    Secure  No
    Expires At End Of Session
    
    Name    .ASPXAUTH
    Value   648767AC72A60DBA49650A361A2FA446BA992F792055EF5B488CADC95DF495315C1C577F1C8E67E67BD937A7AB6CC5DAED85D8D64E4ED7867FC0FC395F48FED7FB631033CE441DE85223E8B3EBAE616C
    Host    www.SITEADDRESS.com
    Path    /
    Secure  No
    Expires Tue, 09 Jun 2009 17:51:31 GMT
    
    Name    ASP.NET_SessionId
    Value   gn5pcymhfsnua455yp45wpej
    Host    www.SITEADDRESS.com
    Path    /
    Secure  No
    Expires At End Of Session
    
    Name    SITENAME
    Value   9610E8515F3DBC088DAC286E1F44311A20CB2BBB57C97F906F49BC878A6C6AC0B9011777402AEA130DCDC521EF4FBB3393DB310083F72EB502AE971183306C24F07F696B3695C67DD73166F1653DF52B
    Host    www.SITEADDRESS.com
    Path    /
    Secure  No
    Expires Tue, 20 Dec 2011 06:14:10 GMT
    
    3 回复  |  直到 13 年前
        1
  •  21
  •   Tom Halladay Amy B    12 年前

    我终于猜出了拼图的最后一块。当我的服务器的应用程序池被回收(由托管提供商配置)时,viewstate加密密钥被自动重新生成。这意味着即使cookies是有效的&非过期(回访前),当用户返回时,百科全书已更改,cookie不再有效。

    解决方案是手动指定静态验证密钥。以下链接可用于为此生成必要的web.config标记。

    http://www.aspnetresources.com/tools/keycreator.aspx

    更新:

    这里有一个更可配置的站点来生成机器密钥

    Source Tree - Generage attribute

    例子:

    <configuration>
      <system.web>
        <machineKey
            validationKey="97CEB2D3DEBF853649EAB851F56F08BA328423F935C97244CF5300925B6FF7D2C43084C73CBAF19D5193755EF7F87A3FFC714675F9197C822BAEEC97E853B91E"
            decryptionKey="A72F69A4650348E3AA249A8179516D67C8553B3D4BD165B9"
            validation="SHA1" />
      </system.web>
    </configuration>
    
        2
  •  19
  •   Paul Suart Wes    17 年前

    FormsAuthentication.SetAuthCookie 方法,而不是自己编写大量代码。

    我相信web.config中的成员资格提供程序设置可能与您在代码中提供的设置冲突,而且您没有提供cookie名称。

    请尝试以下操作:

    if (Membership.ValidateUser(userName, password))
    {
        FormsAuthentication.SetAuthCookie(userName, true); //Creates a cookie named "XXXAuth" - see settings in web.config below
    }
    

    <authentication mode="Forms">
        <forms cookieless="UseCookies" loginUrl="~/SignIn.aspx" name="XXXAuth" slidingExpiration="true" timeout="432000"/>
    </authentication>
    
    
    <membership defaultProvider="XXXMembershipProvider">
        <providers>
            <clear />
            <add name="XXXMembershipProvider" type="System.Web.Security.SqlMembershipProvider" applicationName="XXX" connectionStringName="XXX" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="true" minRequiredPasswordLength="5" minRequiredNonalphanumericCharacters="0" passwordFormat="Hashed" maxInvalidPasswordAttempts="5" passwordAttemptWindow="10" passwordStrengthRegularExpression=""/>
        </providers>
    </membership>
    

    如果您真的想创建一个不确定的登录周期,只需将身份验证块中的“timeout”值更改为更长的值。我相信432000=5天。

    如果希望用户能够显式注销,只需调用以下方法以响应按钮单击(或其他操作):

    FormsAuthentication.SignOut();
    

    希望这有帮助。

        3
  •  2
  •   OtisAardvark    17 年前

    读取代码时,您可能不小心将FormsAuthenticationTicket超时值设置为零。代码中创建票证的行显示:-

    Dim authTicket As FormsAuthenticationTicket = New FormsAuthenticationTicket(Username, True, Expiration.Subtract(Expiration).TotalMinutes)
    

    Expiration.Subtract(Expiration).TotalMinutes 将始终为“0”。

    您最好使用如下所示的手写格式创建票证,这样会减少歧义。

    Public Shared Sub AuthenticateUser(ByVal Username As String)
        Dim Expiration As DateTime = DateTime.Now.AddMonths(3)
        Dim userData As String = String.Empty
    
        Dim authTicket As FormsAuthenticationTicket = _
           New FormsAuthenticationTicket( _
             Username, _
             DateTime.Now, _
             Expiration, _
             true, _
             userData, _
             FormsAuthentication.FormsCookiePath)
        Dim EncryptedTicket As String = FormsAuthentication.Encrypt(authTicket)
        Dim AuthCookie As New HttpCookie(FormsAuthentication.FormsCookieName, EncryptedTicket)
        AuthCookie.Expires = Expiration
        HttpContext.Current.Response.Cookies.Add(AuthCookie)
    End Sub
    

    here 关于“ 了解表单身份验证票据和Cookie

    .