nTierアプリの.Netメンバーシップ
-
05-07-2019 - |
質問
ASP.Net MVCアプリがあり、このアプリ(UI)はビジネスロジックレイヤー(BLL)を参照し、BLLはデータアクセスレイヤー(DAL)を参照するとします。
承認にカスタムメンバーシップおよびロールプロバイダーを利用しています。
メンバーシッププロバイダーを参照する必要があるレイヤーを判断しようとしています。
MVCでは、次の方法で認証チェックを実行できます。
[Authorize(Roles = "SomeRoleName")]
public ActionResult Index()
{
//do something
}
また、BLLで、ユーザーがロールに属しているかどうかを確認することもできます。
public static bool IsRoleEditor(User user, Role userRole)
{
bool retValue = false;
if (user.Application.AppID == UserRole.Application.AppID)
{
if (Roles.IsUserInRole("ModifyRoles"))
{
retValue = true;
}
return retValue;
}
これを行う場合、両方のレイヤーのMembershipクラスを参照およびインスタンス化する必要があります。これは、このようなアプリを設計する正しい方法ですか?冗長性が多いようです。
BLLを持っているので、" [Authorize(Roles =" SomeRoleName")]"の使用は避けます。属性を使用し、代わりにMVCコード内からBLL関数を呼び出して、ユーザーがロールにいるかどうかを確認しますこれを行うと、MVCには認証用のメンバーシッププロバイダーへの参照が必要になります。とにかく、ログインやその他のASPコントロールを利用するには、そうですか?
基地から離れて間違った方向に向かっていますか
解決
私の見解では、これはメンバーシップ/ロール設計の弱点です。
これを回避する方法、たとえば、分散n層アプリのUIとBLL層の両方でロールベースの承認を取得する方法は、関連するビットを公開するサービスをBLL層に公開することです(GetRolesForUserなど)、サーバーでRoleProviderを呼び出すことで実装されます。
次に、BLLによって公開されたサービスを呼び出すことで実装されるクライアントにカスタムRoleProviderを実装します。
この方法では、UI層とBLL層の両方が同じRoleProviderを共有します。 UI層は、現在のユーザーのロールに関する知識を使用してUIを改善できます(たとえば、不正な機能に対応するUIコントロールの非表示/無効化)。また、BLLはユーザーが実行できないことを確認できます。 承認されていないビジネスロジック。
他のヒント
すばらしい質問です。今日も同じことを自問しました。私が持っていたアイデアの1つ(ただし、それが最善の方法かどうかはわかりません)は、アクセスをテストするためにBLLに渡すことができるインターフェイス(例:IRoleProvider)を使用することです。
public static bool IsRoleEditor(User user, IRoleProvider rp)
{
return (rp.IsUserInRole(user,"ModifyRoles"));
}
これにより、BLLでアクセスを確認し、ユニットテストでモックを使用してロジックを確認できます。MVCWebサイトでクラスを作成(またはbaseControllerクラスで実装)するだけです。 IRoleProviderを実装し、ASP.NET認証APIを使用して適切なチェックを行います。
これが役立つことを願っています。
Userオブジェクトを取得してIPrincipalインターフェイスを実装し、レイヤーの周りにスローします。その後、組み込みの[Autorize]属性を引き続き使用できます。
3年以上前に書かれた城について、この記事が役立つ場合があります。途中でIPrincipalにアクセスし始めます。
HTHS
チャールズ
ロールをBLLに渡して、メンバーシップに依存しないようにします。または、MartinBが推奨するようなインターフェイスを使用します。
ステークホルダーが別の形式の認証を使用することを決定し、 Role オブジェクトを使用しなくなった場合、今後どうなりますか?
例:
IsRoleEditor(User user, string[] roles)
{
return roles.Contains("ModifyRoles");
}
MVCのポイントを見逃していないか。 MVCは自然に層に分割されます。モデル(DAL)、コントローラー(BLL)、ビュー(プレゼンテーション)。これらは必要に応じて異なるプロジェクトに配置できますが、コントローラーにはすべてのビジネスロジックがあるため、RoleProviderにアクセスするだけで済みます。
次に、必要に応じて、リポジトリ、パターンなどのパターンを適用してさらに分割します。
Davy
MVCコントローラーを呼び出すには、「UI」はすぐに使えます。MVCの「C」は、BLLの一部です。たとえ、あなたはBLLを呼び出します。ただし、それはあなたの質問のポイントではありません。
「UI」アプリと「BLL」を100%分離するための本当の要件はありますか?」という質問をして、この問題を解決すると思います。両方のコンポーネントがメンバー/ロールプロバイダーへの依存関係を共有している場合は、その依存関係を許可して作業を開始します。
BLLを取り外して新しいBLLを接続する場合、おそらく.NETプロバイダーに依存関係を共有することは、一緒に暮らすことができるものです。それはおそらく大丈夫で、アプリはバラバラにならないかもしれません。
上記のJoeの答えはかなり理にかなっていると思います...
あなたがやっていることは大丈夫だと思います。
承認と認証は、おそらくコントローラーに渡されるサービス層内に存在する必要があります。
コントローラーがプリンシパルとIDを設定し、MVC属性を使用してコントローラーでそれを使用する場合、良いアイデアのように聞こえます。
インターフェイスの背後にMVCメンバーシッププロバイダーを非表示にすると、WinFormsメンバーシッププロバイダー(たとえば)に交換でき、コントローラーのユニットテストが可能になります。
通常、ロールアクセスはBLLには含まれません。アクセスはユーザーインターフェイスの責任です。
とはいえ、上記のポスターが述べているように、IPrincipleインターフェースを活用してください。スレッドレベルでIPrincipleにアクセスできます。
Thread.CurrentPrincipal