18

ASP.NET 3.5 および SQL Server 2005 で構築された Web サイトがあり、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

ウェブ構成:

<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

アップデート:

マシンキーを生成するためのより構成可能なサイトは次のとおりです

ソースツリー-Generage属性

これはセキュリティにわずかな影響を与える可能性があることを認識しています。理論的には、キーがブルートフォース攻撃を受けてビューステートに保存している可能性のあるデータが危険にさらされた場合に備えて、キーを変更する方が安全だと思いますが、機密情報を保存するべきではありません。とにかく本質的に安全ではないため、ビューステート内の情報。

例:

<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

ここには、「フォーム認証チケットと Cookie について」に関する Microsoft KB の優れた記事もあります。

.

于 2009-03-25T22:19:26.300 に答える