我有一个内置于ASP.NET 3.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
答案 0 :(得分:21)
我终于想出了最后一块拼图。当我的服务器的应用程序池被回收(由托管提供商配置)时,正在自动重新生成视图状态加密密钥。这意味着即使饼干是有效的&amp;非过期(返回前访问),当用户返回加密时已更改,并且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>
答案 1 :(得分: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();
希望这有帮助。
答案 2 :(得分: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
“了解表单身份验证故障单和Cookie ”上还有一篇很好的Microsoft知识库文章here