5

デザインの選択

2つのASP.NETMVC承認/役割の設計ストーリーを想定します。どちらも、中間層またはデータストアに対するヒットを最小限に抑えることを目的としています。

  • データベースから「MyRoleProvider」情報をフェッチした後、それはAuthTicketユーザーデータに保存されます。これは、auth-cookieがrole-infoを保持することを意味します。さらに、このストーリーでは、このロール情報の保存と取得は、完全に「MyRoleProvider」の外部にある別個の実装によって行われます。

または...

  • データベースから「MyRoleProvider」情報を取得した後、それはセッションに保存され、そこからアクセスされます。より正確には、クラス「MyRoleProvider」自体が、可能な場合、セッションに内部的にアクセス(および更新)します。

繰り返しになりますが、上記の両方のストーリーは、役割情報を「キャッシュ」することにより、外部ストアにアクセスするまでの待ち時間を最小限に抑えることを目的としています。どちらも正常に動作します。問題は、両方のデザインストーリーの選択が等しく有効かどうかです。そうでない場合、なぜですか?

問題

「(カスタム)RoleProviderは、セッション、キャッシュ、データベースなど、ロール情報がどこにあるかを常に把握している必要があります」という「ベストプラクティス」はどこにも記載されていないようです。

また、 authCookieの「 userData 」にどのようなものを保存してはいけないかを説明する(確かな)ガイダンスはどこにもありません。そこにある小さなドキュメントとガイダンスは、2つのことだけを示唆しています。

  1. 「のuserDataには、」追加のユーザー情報(漠然とした、幅広い文を)保存することができます。私は、追加のサードパーティのアイデンティティ/認証情報を格納関与され、オンラインの唯一のコード例を見てきました。
  2. 'userData'にデータを入れすぎないでください。Cookieが大きくなりすぎて転送できなくなる可能性があります(一部のブラウザではCookieのサイズが制限されています)。

それでおしまい。上記のガイダンスから、「userDataを認証情報のみに制限することがベストプラクティスである」と明確に言われている人はいません。そして、私は確かに「承認またはロール情報を「userData」に入れるのは悪い考えです...」という文書を見たことがありません。

ベストプラクティスを推測しますか?

2つのデザインの選択肢が等しいという私自身の答えは「いいえ」です。私は私の議論を提示し、次の場合にあなたから学びたいと思います:

  1. あなたが同意する。
  2. 私が不必要な大騒ぎをしているので、あなたは同意しません。
  3. あなたは同意しません。私の引数が有効ですが、でもそこにあるより良い私の考えは、最終的に適切ではない理由の引数は。

うまくいけば、ベストプラクティスの概念が答えとして現れるでしょう。今私の議論のために...

私の引数(複数可)

2番目の設計ストーリーは、より優れたモジュール性を表すため、採用する必要があると思います。役割情報は完全に「MyRoleProvider」内で処理されます。最初のオプションは、認証(CookieからIDを抽出する)と承認の問題を不必要に混ぜ合わせます。実際、すべての組み込みASP.NETセキュリティメカニズムは、これら2つのトピックを分離します。基本ASP.NET機能は、ロール情報をauthcookieに格納することはありません。これを確認したい場合は、FormsAuthenticationModule、FormsAuthentication、RolePrincipal実装のIPrincipal、FormsIdentity実装のIIdentityのクラスを反映してみてください。

The ASP.NET RolePrincipal deserves a particular highlight. It permits that role-info is indeed stored in a cookie, but it is a second cookie separate from the auth-cookie. Furthermore, this peculiar idiom still involves consultation with the RoleProvider. See the example section of this MSDN documentation.

Investigating RolePrincipal further, let's look at RolePrincipal.IsInRole(). Although any such IPrincipal derived class combines identity and role information programmatically, the internal implementation still maintains the RoleProvider as the only source of role information (note the reference to Roles.RoleProviders...):

    public bool IsInRole(string role)
    {
        if (this._Identity != null)
        {
            if (!this._Identity.IsAuthenticated || role == null)
            {
                return false;
            }
            else
            {
                role = role.Trim();
                if (!this.IsRoleListCached)
                {
                    this._Roles.Clear();
                    string[] rolesForUser = Roles.Providers[this._ProviderName].GetRolesForUser(this.Identity.Name);
                    string[] strArrays = rolesForUser;
                    for (int i = 0; i < (int)strArrays.Length; i++)
                    {
                        string str = strArrays[i];
                        if (this._Roles[str] == null)
                        {
                            this._Roles.Add(str, string.Empty);
                        }
                    }
                    this._IsRoleListCached = true;
                    this._CachedListChanged = true;
                }
                return this._Roles[role] != null;
            }
        }
        else
        {
            throw new ProviderException(SR.GetString("Role_Principal_not_fully_constructed"));
        }
    }

This kind of ASP.NET “one-stop” deep-assumption of where role information is found, is why role info should be consolidated into the RoleProvider. In short I claim:

  1. 役割情報をCookieに保存する場合、ASP.NETにそれをauth-cookieに結合する組み込み機能がない理由は、ASP.NETが異なるプロバイダー間の関心の分離を強力に維持しているためです。
  2. RoleProviderは、Cookie、セッション、その他の場所に関係なく、role-infoが見つかる可能性がある場所を認識している必要があります。

結論:

ロール情報をauth-cookieに入れないでください。また、(カスタム)RoleProvider、データベース、Webサービス、セッション、キャッシュ、Cookieなど、ロール情報が見つかったすべての場所を認識していることを確認してください。

同意?同意しませんか?考え?

4

2 に答える 2

7

情報がCookie、セッション、またはその他のプロバイダーであるかどうかを実際にキャッシュする場所を決定する際には、さまざまな懸念事項と設計上の選択がたくさんあります。

もちろん、最初の質問は、それをキャッシュする必要があるかどうかです。確かに、かなり静的な情報のためにデータベースに絶えずアクセスすることに関して懸念があります。ただし、誰かをすぐに締め出すことができるという同様の懸念があります。

即時の応答が必要ない場合にのみ、キャッシュが実行可能になります。このため、認証のキャッシュに関するベストプラクティスはありません。また、アプリケーションがそのレベルのセキュリティを必要としない場合は、キャッシュする場所に関するベストプラクティスもありません。

上記が問題ではないと仮定すると、場所とのトレードオフがあります。

クッキークッキー
に入れると、キャプチャして後で再生することができます。また、Cookieはリクエストごとに転送されるため、インターネットトラフィックがわずかに増加します。

セッションセッション
に入れる場合は、単一のWebサーバーに制限するか、Webファーム全体がアクセスできる場所にセッション状態を保存する必要があります。後者のルートを使用する場合は、セッションをデータベースのどこかに保存している可能性が高いため、そもそもセッションにセッションを含める理由が完全に失われます。

Memcacheまたはその他
これは、セッションにロールを保存するのと似ています。ただし、通常は別のサーバーのメモリに保存され、通常は高速です。欠点は、負荷分散されたWebファームの場合、適切にクラスター化されていない限り、これによりさらに別の障害点が追加される可能性があることです。その時点で、プロジェクトの開発、展開、および保守のコストが増加しました。


最終的に、ベストプラクティスはありません。状況に大きく依存するトレードオフの束だけです。率直に言って、このタイプのデータについては、まったくキャッシュしません。通常は比較的小さく、クエリは一般的に非常に高速です。何万人ものユーザーと話している場合はそれを検討するかもしれませんが、そのレベルでは、最終的にここでの選択を明らかにする他の多くの運用上の考慮事項があります。

于 2012-10-18T19:27:30.817 に答える
4

あなたはばかげた質問をしているように私には思えます。正しい心の誰も、認証Cookieに役割データを保存しません。ASP.NETは、暗号化された個別のCookieに格納するRolePrincipalを提供するため、そのようにはなりません。

これはRolePrincipalの実装の詳細であるため、Cookieの問題全体はとにかく無意味です。アプリは、役割データが保存されている場所を認識してはなりません。

だからあなたへの私の質問は...なぜ私たちはこの議論をしているのですか?あなたは、システムによって行われる方法とは逆のことをすることがベストプラクティスであるかどうかを尋ね、次に、誰も使用しないような方法でそれを行うべきではない理由を主張しています。

RoleProviderまた、 Cookieを処理する必要があるというあなたのコメントは真実ではありません。RoleProviderはを作成しませんRolePrincipal。これは、フレームワーク内で行われます。Cookieを使用するかどうかの選択はRoleProvider、ではなく、RoleManagerModuleフレームワーククラスによって提供され、フレームワークIPrincipalによってインスタンス化される方法です。

の例は、とRolePrincipalは何の関係もありませんRoleProvider。実際、RoleManagerModuleこの機能を制御します。 RoleManagerModuleIISにHttpModuleインストールされ、パイプラインの一部として実行されるです。についても知りませんRoleProvider。基本的に、これが意味するのは、ロールが非常に低いレベルでCookieから入力され、 `RoleProviderが実行に移ったときに、すでにそこにあるロールが見つかった場合、何も実行しないということです。 。

于 2012-10-18T19:40:42.797 に答える