カスタムロールプロバイダーを作成していて、コントローラーのロールを指定するAuthorize属性を設定すると、次のようにうまく機能します。
[Authorize(Roles="SuperAdmin")]
public class SuperAdminController : Controller
...
しかし、ユーザーがこのコントローラーにアクセスできない場合、ユーザーはログインページにリダイレクトされます。 「AcessDenied.aspx」ページにリダイレクトするにはどうすればよいですか?
[AccessDeniedAuthorize(Roles="SuperAdmin")]
public class SuperAdminController : Controller
AccessDeniedAuthorizeAttribute.cs:
public class AccessDeniedAuthorizeAttribute : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
if(filterContext.Result is HttpUnauthorizedResult)
{
filterContext.Result = new RedirectResult("~/AcessDenied.aspx");
}
}
}
これが、eu-ge-neの回答に基づく私の解決策です。 Mineは、ユーザーがログインしていない場合はログインページに正しくリダイレクトしますが、ログインしているがそのページを表示する権限がない場合は、アクセス拒否ページにリダイレクトします。
[AccessDeniedAuthorize(Roles="SuperAdmin")]
public class SuperAdminController : Controller
AccessDeniedAuthorizeAttribute.cs:
public class AccessDeniedAuthorizeAttribute : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
{
filterContext.Result = new RedirectResult("~/Account/Logon");
return;
}
if (filterContext.Result is HttpUnauthorizedResult)
{
filterContext.Result = new RedirectResult("~/Account/Denied");
}
}
}
AccountController.cs:
public ActionResult Denied()
{
return View();
}
Views/Account/Denied.cshtml:(Razor構文)
@{
ViewBag.Title = "Access Denied";
}
<h2>@ViewBag.Title</h2>
Sorry, but you don't have access to that page.
tvanfosson の Answer を見てみましょう この非常によく似た質問 、これは私がやっていることです(tvanfossonのおかげで)、今私はただ言わなければなりません:
[MyAuthorize(Roles="SuperAdmin",ViewName="AccessDenied")]
public class SuperAdminController : Controller
...
ユーザーがロールにない場合、ユーザーはViewNameで指定されたビューを取得します。
リダイレクトが常に最良のソリューションであるとは限らない
標準のhttpコード403を使用します。
return new HttpStatusCodeResult(HttpStatusCode.Forbidden);
ログオンページをハードコーディングする必要をなくし、オプションで属性内のアクセス拒否ビューを設定することにより、Mattの回答を少し改善しました。
public class AccessDeniedAuthorizeAttribute : AuthorizeAttribute
{
public string AccessDeniedViewName { get; set; }
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
if (filterContext.HttpContext.User.Identity.IsAuthenticated &&
filterContext.Result is HttpUnauthorizedResult)
{
if (string.IsNullOrWhiteSpace(AccessDeniedViewName))
AccessDeniedViewName = "~/Account/AccessDenied";
filterContext.Result = new RedirectResult(AccessDeniedViewName);
}
}
}
Vicの回答に基づいて、アプリケーションの領域ごとに異なるAccess Deniedページを表示できるようにしています。代わりにRedirectToRouteResult
を返すことで、アプリケーションのルートを基準にしたURLにリダイレクトする代わりに、現在の領域のコントローラーとアクションにリダイレクトしました。
public class AccessDeniedAuthorizeAttribute : AuthorizeAttribute
{
public string AccessDeniedController { get; set; }
public string AccessDeniedAction { get; set; }
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
if (filterContext.HttpContext.User.Identity.IsAuthenticated &&
filterContext.Result is HttpUnauthorizedResult)
{
if (String.IsNullOrWhiteSpace(AccessDeniedController) || String.IsNullOrWhiteSpace(AccessDeniedAction))
{
AccessDeniedController = "Home";
AccessDeniedAction = "AccessDenied";
}
filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { Controller = AccessDeniedController, Action = AccessDeniedAction }));
}
}
}
Vic Alcazarのほんの小さな更新、リダイレクトにリクエストURLの詳細を追加しました。これにより、拒否されたアクセスの詳細と必要に応じて誰がアクセスしたかをログに記録できます
public class AccessDeniedAuthorizeAttribute : AuthorizeAttribute
{
public string AccessDeniedViewName { get; set; }
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
if (filterContext.HttpContext.User.Identity.IsAuthenticated &&
filterContext.Result is HttpUnauthorizedResult)
{
if (string.IsNullOrWhiteSpace(AccessDeniedViewName))
AccessDeniedViewName = "~/Account/AccessDenied";
var requestUrl = filterContext.HttpContext.Request.Url;
filterContext.Result = new RedirectResult(String.Format("{0}?RequestUrl={1}", AccessDeniedViewName, requestUrl));
}
}
}
public class AccessDeniedAuthorizeAttribute : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
if (filterContext.Result is HttpUnauthorizedResult && WebSecurity.IsAuthenticated)
{
filterContext.Result = new RedirectResult("~/Account/AccessDenied");
}
}
}