18

我有一个使用 sql 成员资格提供程序在 ASP.NET 3.5 和 SQL Server 2005 中构建的网站,并且可能形成身份验证。

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

正在发生的事情是用户登录,在会话中保持登录状态,然后在他们下次到达时,他们被注销。

如何让登录持久化?

这是技术细节,我已经尝试了许多持续时间的变化。

 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

网络配置:

<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
4

3 回答 3

21

我终于弄清楚了最后一块拼图。当我的服务器的应用程序池被回收(由托管服务提供商配置)时,视图状态加密密钥正在自动重新生成。这意味着即使 cookie 有效且未过期(返回前访问),当用户返回时,加密已更改,cookie 不再有效。

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

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

更新:

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

源树 - 生成属性

我意识到这可能会产生轻微的安全影响,我想从理论上讲,如果您的密钥被暴力破解并危及您可能存储在视图状态中的任何数据,那么更改密钥会更安全,但您可能不应该存储敏感信息视图状态中的信息,因为无论如何它本质上都不是安全的。

例子:

<configuration>
  <system.web>
    <machineKey
        validationKey="97CEB2D3DEBF853649EAB851F56F08BA328423F935C97244CF5300925B6FF7D2C43084C73CBAF19D5193755EF7F87A3FFC714675F9197C822BAEEC97E853B91E"
        decryptionKey="A72F69A4650348E3AA249A8179516D67C8553B3D4BD165B9"
        validation="SHA1" />
  </system.web>
</configuration>
于 2009-06-26T14:50:49.150 回答
19

我认为您最好使用该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
}

结合 web.config 中的以下设置:

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

如果您真的想创建无限期的登录期,只需将身份验证块中的“超时”值更改为更长的值。我相信 432000 = 5 天。

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

FormsAuthentication.SignOut();

希望这可以帮助。

于 2009-03-26T10:23:37.697 回答
2

阅读您的代码时,您可能不小心将 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

这里还有一篇很好的 Microsoft KB 文章“了解表单身份验证票证和 Cookie

.

于 2009-03-25T22:19:26.300 回答