Making user login persistant with ASP .Net Membership Making user login persistant with ASP .Net Membership asp.net asp.net

Making user login persistant with ASP .Net Membership


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>


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.


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"

.