そのため、この ID が現在認証されているユーザーのものであることを常に確認する必要があります。現在認証されているユーザーは、フォーム認証 Cookie に格納されており、値が暗号化されているため、ユーザーが変更することはできません。この Cookie は、ユーザーがログインしたときに発行され、インスタンスがある場所ならどこでもアクセスできますHttpContextBase
(MVC パターンの V および C 部分のほとんどどこでも)。
たとえば、次のようにします。
[Authorize]
public ActionResult Foo(int id)
{
string currentUser = httpContext.User.Identity.Name;
// TODO: go ahead and check in your backed that the id
// belongs to the currently connected user
...
}
アプローチの DRYness は言うまでもなく、すべてのコントローラー アクションでこれらのチェックを何度も何度も記述することは、すぐに退屈になる可能性があることは明らかです。そのため、コントローラー アクションに入る前にこれらのチェックを実行するカスタムの Authorize 属性を記述することをお勧めします。次に、コントローラーのアクションをこのカスタム属性で装飾します。コードがアクション内に到達した場合、現在のユーザーがパラメーターとして渡された ID の所有者であることを確認できます。この ID がパラメーターとして渡される方法は、実際には問題ではありません。ルート データ、クエリ文字列、POST など、何でもかまいません。ユーザーは好きなだけ変更できます。重要な部分は、彼が入力した値がドメイン認証ロジックと一貫していることを確認することです。
そう:
public class AuthorizeOwnerAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
var authorized = base.AuthorizeCore(httpContext);
if (!authorized)
{
// the user is either not authenticated or not authorized
// no need to continue any further
return false;
}
// at this stage we know that the user is authenticated and
// authorized (in roles), so let's go ahead and see who this
// user is
string username = httpContext.User.Identity.Name;
// now let's read the id. In this example I fetch it from
// the route data but you could adapt according to your needs
string id = httpContext.Request.RequestContext.RouteData.Values["id"] as string;
// Now that we know the user and the id let's go ahead and
// check in our backend if the user is really the owner
// of this id:
return IsOwner(username, id);
}
private bool IsOwner(string username, string id)
{
// go ahead and hit the backend
throw new NotImplementedException();
}
}
その後:
[AuthorizeOwner]
public ActionResult Foo(int id)
{
...
}