デザインの選択
2つのASP.NETMVC承認/役割の設計ストーリーを想定します。どちらも、中間層またはデータストアに対するヒットを最小限に抑えることを目的としています。
- データベースから「MyRoleProvider」情報をフェッチした後、それはAuthTicketユーザーデータに保存されます。これは、auth-cookieがrole-infoを保持することを意味します。さらに、このストーリーでは、このロール情報の保存と取得は、完全に「MyRoleProvider」の外部にある別個の実装によって行われます。
または...
- データベースから「MyRoleProvider」情報を取得した後、それはセッションに保存され、そこからアクセスされます。より正確には、クラス「MyRoleProvider」自体が、可能な場合、セッションに内部的にアクセス(および更新)します。
繰り返しになりますが、上記の両方のストーリーは、役割情報を「キャッシュ」することにより、外部ストアにアクセスするまでの待ち時間を最小限に抑えることを目的としています。どちらも正常に動作します。問題は、両方のデザインストーリーの選択が等しく有効かどうかです。そうでない場合、なぜですか?
問題
「(カスタム)RoleProviderは、セッション、キャッシュ、データベースなど、ロール情報がどこにあるかを常に把握している必要があります」という「ベストプラクティス」はどこにも記載されていないようです。
また、 authCookieの「 userData 」にどのようなものを保存してはいけないかを説明する(確かな)ガイダンスはどこにもありません。そこにある小さなドキュメントとガイダンスは、2つのことだけを示唆しています。
- 「のuserDataには、」追加のユーザー情報(漠然とした、幅広い文を)保存することができます。私は、追加のサードパーティのアイデンティティ/認証情報を格納関与され、オンラインの唯一のコード例を見てきました。
- 'userData'にデータを入れすぎないでください。Cookieが大きくなりすぎて転送できなくなる可能性があります(一部のブラウザではCookieのサイズが制限されています)。
それでおしまい。上記のガイダンスから、「userDataを認証情報のみに制限することがベストプラクティスである」と明確に言われている人はいません。そして、私は確かに「承認またはロール情報を「userData」に入れるのは悪い考えです...」という文書を見たことがありません。
ベストプラクティスを推測しますか?
2つのデザインの選択肢が等しいという私自身の答えは「いいえ」です。私は私の議論を提示し、次の場合にあなたから学びたいと思います:
- あなたが同意する。
- 私が不必要な大騒ぎをしているので、あなたは同意しません。
- あなたは同意しません。私の引数が有効ですが、でもそこにあるより良い私の考えは、最終的に適切ではない理由の引数は。
うまくいけば、ベストプラクティスの概念が答えとして現れるでしょう。今私の議論のために...
私の引数(複数可)
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:
- 役割情報をCookieに保存する場合、ASP.NETにそれをauth-cookieに結合する組み込み機能がない理由は、ASP.NETが異なるプロバイダー間の関心の分離を強力に維持しているためです。
- RoleProviderは、Cookie、セッション、その他の場所に関係なく、role-infoが見つかる可能性がある場所を認識している必要があります。
結論:
ロール情報をauth-cookieに入れないでください。また、(カスタム)RoleProviderが、データベース、Webサービス、セッション、キャッシュ、Cookieなど、ロール情報が見つかったすべての場所を認識していることを確認してください。
同意?同意しませんか?考え?