さまざまなロールに基づいてアクセスする MVC Web サイトがあります。ユーザーがシステムにログインすると、承認されているページへのナビゲーションが表示されます。ただし、一部のユーザーは、直接 URL を使用してページにアクセスしようとする場合があります。その場合、システムは自動的にユーザーをログイン ページにリダイレクトします。ログイン ページの代わりに、別のビュー (承認されていない) にリダイレクトします。
Web.Config には次のエントリがあります。
<customErrors mode="On">
<error statusCode="401" redirect="~/Home/Unauthorized" />
<error statusCode="404" redirect="~/Home/PageNotFound" />
</customErrors>
<authentication mode="Forms">
<forms name="Development" loginUrl="~/Account/Login" cookieless="UseCookies" timeout="120"></forms>
</authentication>
これらのルートを Global.asax.cs にも登録しました。
routes.MapRoute(
name: "Unauthorized",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Unauthorized", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "PageNotFound",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "PageNotFound", id = UrlParameter.Optional }
);
それは十分でしょうか?
ベストアンサー1
いくつか調査した結果、この問題に対する最も簡単な答えは、jbbi のものと非常によく似たカスタム承認を作成することだと思いました (ただし、"new HttpUnauthorizedResult()" は内部的に自動的にログインにリダイレクトするため、これは機能しませんでした - 少なくとも ID 付きの MVC 5 では)
public class CustomAuthorize : AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
{
//if not logged, it will work as normal Authorize and redirect to the Login
base.HandleUnauthorizedRequest(filterContext);
}
else
{
//logged and wihout the role to access it - redirect to the custom controller action
filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { controller = "Error", action = "AccessDenied" }));
}
}
}
使用方法はデフォルトのAuthorizeと同じです。
[CustomAuthorize(Roles = "Administrator")]
次に、正しく動作させるために、エラー ページの HTTP コードを送信することを忘れないでください。たとえば、コントローラーで次のようにします。
public ActionResult AccessDenied()
{
Response.StatusCode = 403;
return View();
}
簡単で、機能し、私 (.net mvc 初心者) でも理解できます。
注記:401 コードでは同じようには動作しません。常に 401 を引き継いで、内部的にログインにリダイレクトします。ただし、私のケースでは、定義上、403 も適しています。