Making user login persistant with ASP .Net Membership

て烟熏妆下的殇ゞ 提交于 2019-11-27 01:21:22

问题


I have a website that is built in ASP.NET 3.5 & SQL Server 2005, using the sql membership provider, and presumably forms authentication.

Since security needs on my site are very low, I would like to authenticate once, and then keep the log in persisted indefinitely (without giving the user the choice).

What is happening is that the user logs in, stays logged in for the session, and then the next time they arrive, they are logged out.

How can I get the log-in persisted?

Here's the technical details, I have experimented with many variations of durations.

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

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

Edit: Here is the cookie information that is getting stored by the client:

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

回答1:


I finally figured out the last piece of the puzzle. When the app pool of my server was being recycled (configured by the hosting provider), the viewstate encryption key was being auto-re-generated. This meant that even though the cookies were valid & non expired (pre-return visit), when the user returned the encyrption had changed, and the cookie was no longer valid.

The solution was to manually specify a static validation key. The following link can be used to generate the neccessary web.config tag for this.

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

UPDATE:

Here's a more configurable site to generate Machine Key

Source Tree - Generage attribute

I realize that this might have a minor security impact, I guess theoritically it's safer to have a changing key in case your key gets brute forced and compromises any data you might be storing in the view state, but you probably shouldn't be storing sensitive information in the viewstate as it's not inherently safe anyway.

Example:

<configuration>
  <system.web>
    <machineKey
        validationKey="97CEB2D3DEBF853649EAB851F56F08BA328423F935C97244CF5300925B6FF7D2C43084C73CBAF19D5193755EF7F87A3FFC714675F9197C822BAEEC97E853B91E"
        decryptionKey="A72F69A4650348E3AA249A8179516D67C8553B3D4BD165B9"
        validation="SHA1" />
  </system.web>
</configuration>



回答2:


I think you'd be better-off using the FormsAuthentication.SetAuthCookie method rather than writing a lot of code yourself.

I believe your membership provider settings in the web.config may be conflicting with the settings you're providing in code, plus you're not providing a cookie name.

Try the following:

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

In conjunction with the following settings in 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>

Simply change the "timeout" value in the authentication block to be a longer value if you really want to create an indefinite log-in period. I believe 432000 = 5 days.

If you want your users to be able to explicitly log-out, simply call the following method in response to a button click (or whatever):

FormsAuthentication.SignOut();

Hope this helps.




回答3:


Reading your code you might have accidently set the FormsAuthenticationTicket timeout value to zero. The line in your code where you create the ticket reads: -

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

The value of Expiration.Subtract(Expiration).TotalMinutes will always be "0".

You may be better using the longhand format for creating the ticket as follows which would result in less ambiguity.

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

There is also a good Microsoft KB article here on "Understanding the Forms Authentication Ticket and Cookie"

.



来源:https://stackoverflow.com/questions/682788/making-user-login-persistant-with-asp-net-membership

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!