Rendre l'utilisateur login persistant avec ASP.Net membres
j'ai un site web qui est construit en ASP.NET 3.5 & SQL Server 2005, en utilisant le fournisseur d'adhésion sql, et forme probablement l'authentification.
puisque les besoins de sécurité sur mon site sont très faibles, je voudrais m'authentifier une fois, puis garder le log in a persisté indéfiniment (sans donner le choix à l'utilisateur).
Ce qui se passe est que l'utilisateur se connecte, reste connecté pendant la session, et puis la prochaine fois qu'ils arrivent, ils sont déconnecter.
Comment puis-je obtenir la connexion a persisté?
Voici les détails techniques, j'ai expérimenté avec de nombreuses variations de durées.
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: Voici les informations de cookie qui sont stockées par le 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
3 réponses
j'ai enfin trouvé la dernière pièce du puzzle. Lorsque le pool d'applications de mon serveur était recyclé (configuré par le fournisseur d'hébergement), la clé de cryptage viewstate était générée automatiquement. Cela signifie que même si les cookies étaient valides et non expirés (visite avant le retour), lorsque l'Utilisateur a retourné l'encodage avait changé, et le cookie n'était plus valide.
la solution était de spécifier manuellement une clé de validation statique. Le lien suivant peut être utilisé pour générer le web nécessaire.une étiquette de configuration pour ça.
http://www.aspnetresources.com/tools/keycreator.aspx
mise à jour:
voici un site plus configurable pour générer une Clé Machine""
arbre généalogique de la Source
je me rends compte que cela pourrait avoir un impact mineur sur la sécurité, je suppose théoritiquement, il est plus sûr d'avoir une clé changeante au cas où votre clé soit forcée et compromet toutes les données que vous pourriez stocker dans l'état de la vue, mais vous ne devriez probablement pas stocker des informations sensibles dans l'état de la vue car il n'est pas intrinsèquement sûr de toute façon.
exemple:
<configuration>
<system.web>
<machineKey
validationKey="97CEB2D3DEBF853649EAB851F56F08BA328423F935C97244CF5300925B6FF7D2C43084C73CBAF19D5193755EF7F87A3FFC714675F9197C822BAEEC97E853B91E"
decryptionKey="A72F69A4650348E3AA249A8179516D67C8553B3D4BD165B9"
validation="SHA1" />
</system.web>
</configuration>
je pense que vous seriez mieux-en utilisant la méthode FormsAuthentication.SetAuthCookie
plutôt que d'écrire beaucoup de code vous-même.
je crois que vos paramètres de fournisseur d'adhésion dans le web.config peut être en conflit avec les paramètres que vous fournissez dans le code, en plus vous ne fournissez pas un nom de cookie.
essayez ce qui suit:
if (Membership.ValidateUser(userName, password))
{
FormsAuthentication.SetAuthCookie(userName, true); //Creates a cookie named "XXXAuth" - see settings in web.config below
}
en conjonction avec les paramètres suivants dans 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>
Il suffit de changer la valeur "timeout" dans le bloc d'authentification pour qu'elle soit plus longue si vous voulez vraiment créer une période d'ouverture de session indéfinie. Je crois que 432000 = 5 jours.
si vous voulez que vos utilisateurs puissent se déconnecter explicitement, appelez simplement la méthode suivante en réponse à un clic de bouton (ou autre):
FormsAuthentication.SignOut();
Espérons que cette aide.
en lisant votre code, vous avez peut-être accidentellement réglé la valeur de délai FormsAuthenticationTicket à zéro. La ligne dans votre code où vous créez le billet se lit: -
Dim authTicket As FormsAuthenticationTicket = New FormsAuthenticationTicket(Username, True, Expiration.Subtract(Expiration).TotalMinutes)
La valeur de Expiration.Subtract(Expiration).TotalMinutes
sera toujours "0".
il est peut-être préférable d'utiliser le format longhand pour créer le billet de la façon suivante, ce qui se traduirait par moins d'ambiguïté.
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
Il ya aussi un bon article de Microsoft KB ici " Comprendre les Formulaires de Ticket d'Authentification et de Témoin "
.