私は、非常に一般的なタスクであると私が信じていることをどの方向に進めるかについて、ちょっとしたつまずきにぶつかりました。ログインしたユーザーがデータの編集を許可されていることをどこで確認しますか。この場合、aUser
には Id、EmailAddress、Name、およびAddress
オブジェクトのコレクションがあります。にAddress
はいくつかのプロパティが含まれており、そのうちの 1 つは UserId であり、所属するユーザーの ID です。Address
ユーザーは、自分に属するオブジェクトの編集のみを許可する必要があります。いつ/どこで編集するAddress
ときは、ユーザーが編集を許可されていることを確認します。
今週、ASP.NET MVC3 を学習したばかりで、それを実践しています。デフォルトの MembershipProvider を使用してユーザーをログインさせる Web アプリケーションを作成しました (後日、これをカスタムのものに置き換えます)。最終的な結果として、ログイン後User.Identity.Name
、コントローラーのプロパティはユーザーの電子メール アドレスを返します。
ユーザーが自分の詳細を表示したい場合は、 でAddresses
アクションを呼び出しますAccountController
。以下のように。
[Authorize]
public ActionResult Addresses()
{
IEnumerable<Address> addresses = _myService.GetUserAddresss(User.Identity.Name));
return View(addresses);
}
ユーザーが住所の詳細を編集したい場合、住所を取得して表示するアクションと、編集内容を住所に保存するアクションを呼び出すことができます。
[Authorize]
public ActionResult Address(int id)
{
Address address= _myService.GetAddress(id));
return View(address);
}
[Authorize]
[HttpPost]
public ActionResult Address(EditAddressModel model)
{
Address address = _myService.SaveDetail(model.Address));
return View(address );
}
上記の方法の欠点は、ユーザーが url にアクセスした場合../Account/Address/12
です。Address
その後、作成したかどうかに関係なく、ID 12の を表示および編集できます(存在する場合)。
私はN層のアプローチに従っています。そのため、コントローラーがサービスと通信し、サービスがビジネス ロジック レイヤーと通信し、リポジトリと通信し、最後に Entity Framework 4 を使用してデータベースと通信します。承認チェックはどこで行う必要がありますか?
次の解決策を検討しましたが、適切なアプローチを決定できません。
アイデア1
コントローラー クラスでは、コントローラーが User.Identity.Name プロパティにアクセスできるため。このプロパティを使用して、サービスから返されたアドレスのユーザー ID が現在ログインしているユーザーと一致するかどうかを確認できます。そうでない場合は、エラー ページを表示します。それ以外の場合は、通常どおり表示/編集します。
Address
利点 - シンプルな実装。サービスがオブジェクトを返した後に if ステートメントを追加するだけです。コントローラーは User.Identity.Name にアクセスできます。
欠点 - データはコントローラーに返されます。コントローラーは、ユーザーがそれを見ることができないと判断します。「ユーザーだけが自分のアドレスを編集できる」というビジネスロジックがコントローラーに忍び込んでいるような気がします。
アイデア2
ビジネス層。コントローラーは、userId と detailId ( _myService.GetAddress(User.Identity.Name, detailId));
) を使用してサービスを呼び出します。これにより、ビジネス レイヤーが呼び出されます。ビジネス層にはメソッドpublic Address GetAddress(int userId, int addressId)
があります ビジネス層は、データベースから を取得するように要求されるとAddress
、返されたアドレスがユーザーのものであることを確認して返します。そうでない場合は null を返します。したがって、コントローラーはサービスから null 応答を取得し、適切なエラー メッセージを表示します。
利点 - ユーザーが詳細を編集するだけのビジネス ロジックは、ビジネス レイヤーにあります。
短所 - ビジネス ロジックは User.Identity.Name にアクセスできないため、サービス クラスとビジネス クラスの各メソッドには userId パラメータが必要になります。
アイデア3
上記と同様に、Service および Business レイヤー クラスには UserId というプロパティがあります。これは、ユーザーがデータベース リソースにアクセスできるかどうかを確認するために使用されます。これは、作成中またはサービスを呼び出す前に設定できます。すなわち
[Authorize]
public ActionResult Address(int id)
{
_myService.User = User.Identity.Name;
Address address = _myService.GetAddress(id));
return View(address);
}
利点 - ユーザーが詳細を編集するだけのビジネス ロジックは、ビジネス レイヤーにあります。各メソッド呼び出しに userId を渡す必要はありません。
欠点 - このアプローチを使用する例を見たことがありません。そして、私はそれが正しいとは思いません。サービス層として WCF を使用しているわけではありません。しかし、もしそうなら、この余分なプロパティを持つことはうまくいかないでしょう。
アイデア4
ビジネス層の User.Identity.Name にアクセスします。コントローラーからサービスを介してビジネス層に渡す必要はありません。それが可能かどうかはわかりません。