2009-08-14 8 views
28

カスタムロールプロバイダを作成していて、コントローラでロールを指定するAuthorize属性を設定しています。これはうまくいきます。ASP.NET MVCがカスタムロールプロバイダを使用してアクセス拒否ページにリダイレクトする

[Authorize(Roles="SuperAdmin")] 
public class SuperAdminController : Controller 
... 

しかし、ユーザーがこのコントローラにアクセスできない場合、彼はログインページにリダイレクトされます。 彼を "AcessDenied.aspx"ページにリダイレクトする方法はありますか?

答えて

42
[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"); 
     } 
    } 
} 
+6

ユーザーがログインしてページにアクセスしようとすると、AccessDeniedページにリダイレクトされます。良い。しかし、ユーザーがログインしていなければ、AccessDeniedページにリダイレクトされます。悪い。その場合、ログインページにリダイレクトされます。 –

+3

ユーザーがもはや存在しない場合にページをリダイレクトするには、base.OnAuthorization()メソッド呼び出しの後に、Threading.Thread.CurrentPrincipalが存在するかどうかをチェックするコードの残りの部分にifステートメントを追加します。 Identity.IsAuthenticated。この方法では、ユーザーが認証されていない限り、ユーザーはAccessDeniedページに誘導されます。デフォルトのアクション(ログインページにリダイレクト) – Frinavale

+0

このクラスはどこに置かれますか?コントローラーで? – Jay

8

は、this very similar questionからtvanfossonさんAnswerを見てみましょう。これは、私が(tvanfossonに感謝を)やっているものですので、今私は言っている:

[MyAuthorize(Roles="SuperAdmin",ViewName="AccessDenied")] 
public class SuperAdminController : Controller 
... 

ユーザーがロールに属していない場合、ViewNameで指定されたビューが表示されます。

22

私の解決策は、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(); 
} 

ビュー/アカウント/ Denied.cshtml:(レイザー構文)

@{ 
    ViewBag.Title = "Access Denied"; 
} 

<h2>@ViewBag.Title</h2> 

Sorry, but you don't have access to that page. 
+1

受け入れられた答えからの完璧な変更、感謝の仲間 –

6

わずかマットの答えへの改善b yのログオンページハードコードする必要性を回避し、必要に応じてアクセス権を設定するには、属性内のビューを拒否:

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); 
     } 
    } 
} 
0
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"); 
      } 
     } 
    } 
0

私は私がのために別のアクセス拒否のページを持つことができるように、ヴィックの答え上に構築されてきました各アプリケーションの領域。その代わりに、それは現在のエリアのコントローラとアクションにリダイレクトするアプリケーションのルートからの相対URLにリダイレクトするのではなく、RedirectToRouteResultを返すことでそれをやった:

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 })); 
     } 
    } 
} 
0

ヴィックアルカサル、 追加詳細にほんの少しの更新リダイレクト のリクエスト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)); 
     } 
    } 
} 
5

をしたい場合は、リダイレクトが常に最善のソリューション

使用スタンではないが誰であるかによってすることができますdard httpコード403:

return new HttpStatusCodeResult(HttpStatusCode.Forbidden); 
関連する問題