1

ASP.NET MVC で、非アクティブ状態が約 20 分間続くと、ユーザーが強制的に再ログインするという問題が発生しています。

フォーム認証を使用しており、構成ファイルのタイムアウトを次のように増やしました。

<authentication mode="Forms">
  <forms loginUrl="~/Account/LogOn" timeout="9999999" />
</authentication>

また、構成ファイルでセッションタイムアウトを次のように設定しています。

<sessionState timeout="120"></sessionState>

これは、Rockford Lhotka の CSLA ASP.NET MVC の例に基づいており、global.asax に次のものがあります。

    protected void Application_AcquireRequestState(object sender, EventArgs e)
    {
        if (HttpContext.Current.Handler is IRequiresSessionState)
        {
            if (Csla.ApplicationContext.AuthenticationType == "Windows")
                return;
            System.Security.Principal.IPrincipal principal;
            try
            {
                principal = (System.Security.Principal.IPrincipal)
                    HttpContext.Current.Session[MyMembershipProvider.SESSION_KEY];
            }
            catch
            {
                principal = null;
            }
            if (principal == null)
            {
                if (this.User.Identity.IsAuthenticated && this.User.Identity is FormsIdentity)
                {
                    // no principal in session, but ASP.NET token
                    // still valid - so sign out ASP.NET
                    FormsAuthentication.SignOut();
                    this.Response.Redirect(this.Request.Url.PathAndQuery);
                }
                // didn't get a principal from Session, so
                // set it to an unauthenticted PTPrincipal
                BusinessPrincipal.Logout();
            }
            else
            {
                // use the principal from Session
                Csla.ApplicationContext.User = principal;
            }
        }
    }

私が言えることから、120分間非アクティブになった後にのみタイムアウトする必要があります...しかし、何らかの理由で、20分間非アクティブになると常にタイムアウトするようです。なぜこれが起こっているのか、アイデアはありますか?

フォーム認証をダンプしてセッション経由で自分で処理するというアイデアをいじっていますが、 [Authorize] 属性などの機能が失われるのではないかと心配しています。この道を下らないようにしています。

カスタム プリンシパル オブジェクトを Cookie として保存することはできますか? すべてのページまたはアクションに対してユーザーを認証/承認する必要はありません。

私は髪を失っています...急速に!=)

4

4 に答える 4

4

FormsAuthentication と SessionState の懸念を混在させることは、多くのレベルで悪い考えです。得られた回答から気づいているからです。

カスタム プリンシパルを記述する情報が少ない場合は、フォーム チケットの UserData メンバーに格納することをお勧めします。それが目的です。

次に、有効なチケットでのみ有効なカスタム データがチケットと共に保存されます。

多くの問題が解決され、ムーチョ コードが不要になりました。

これは、チケットの処理に役立つヘルパー クラスです。

警告: 実際には、http cookie の最大サイズは公式の 4k 制限をわずかに下回っており、暗号化により約半分に削減されます。

プリンシパル データを含むチケットが 2k 未満に収まることを確認できれば、問題ありません。プリンシパルのカスタム シリアル化を作成すると役立ちます。たとえば、名前=値のペアは、データが連携する場合にうまく機能します。

幸運を。

于 2010-03-05T07:28:03.880 に答える
2

セッションを介して処理するだけでは不十分な場合があります。IISがアプリケーションをリサイクルしている可能性があるため、すべてのセッションが破棄されます。

見る

于 2010-03-04T17:40:10.067 に答える
2

これで問題が解決したことを願っていますが、他の誰かが同じ問題に遭遇した場合に備えて、同じテンプレートを使用して記述されたコードのデバッグを担当しました。ここにいくつかの考えがあります。

1) フォーム チケットには、その値にエンコードされたタイムアウトがあります。そこにあるサンプルコードのほとんどは、フォーム認証構成からプルするのではなく、このタイムアウトをハードコーディングしているため、web.config を見ているだけではすべて問題ないように見えますが、カスタム セキュリティ コードは web.config 値を無視しています。「new FormsAuthenticationTicket」のコードを調べて、有効期限のために何をしているかを確認してください。

2) フォーム Cookie の Cookie 値にタイムアウトが設定されています。いくつかのサンプル コードでは、このタイムアウトをハードコードしています。セキュリティ Cookie で cookie.Expires を設定しているかどうかを確認します。(FormsAuthentication メソッドは make-a-cookie-with-userdata メソッドを公開せず、通常は userdata を使用してロールなどの情報を少し保存する必要があるため、カスタム認証はここで予想よりも多くのコードを手動で構築する傾向があります。の)

3) 一部のクライアントは、応答リダイレクトで Cookie を設定しません。場合によっては、設定したものとは異なる Cookie が返されることもあります。たとえば、任意の時点でアプリ パスまたはドメインを変更した場合、ユーザーが 2 つの有効な Cookie を保持している可能性があり、ここで再度ログインしようとすると、1 つだけがクリアされます。さて、このコードは基本的に「ユーザーにはいくつかのセッション情報があり、ログインしていましたが、彼らのセッションには私が期待していたプリンシパルが含まれていなかったため、再度ログインするようにリダイレクトします。」彼らがあなたの認証 Cookie をリッスンしない場合、または予期しない認証 Cookie を持っている場合 (ある時点でドメインまたはパスの値を変更し、/oldpath Cookie がまだ設定されている可能性があります)、これは無限ループになる可能性があります。 . そうでないことがわかったらすぐに、サーバー側でセッションを無効にすることをお勧めします。必要なデータがある: Session.Clear() - これにより、リダイレクト後にこの状況に陥る可能性が低くなります。(クライアントの動作を信頼せずにサーバー側を回復するという観点からは、プリンシパルオブジェクトを再構築してセッションに入れる方が実際には少し安全ですが、これがどのように少なくなるかがわかります安全。)

また、正しく機能するために Cookie を変更するリダイレクトに頼るよりも、ログイン ページに Server.Transfer を実行する方が安全です。リダイレクト ループに陥った場合は、server.transfer によって確実に終了されます。

于 2010-09-06T06:19:11.530 に答える