2016-10-01 143 views
1

我試着創建一個簡單的過濾器,看看用戶是否在一個名爲「系統管理員」的角色,基本上不得不做[Authorize(Roles = "System Administrator")]的短手。我認爲這將是相當簡單的,但我也是相當新的MVC,所以也許我忽略了一些東西。ASP.Net Identity 2 - 爲什麼我的過濾器不工作?

這裏是我的代碼:

using System.Web.Mvc; 

namespace site_redesign_web.Filters 
{ 
    public class SystemAdminFilter : ActionFilterAttribute 
    { 
     string SysAdminRole = "System Administrator"; 

     public override void OnActionExecuting(ActionExecutingContext filterContext) 
     { 
      if (filterContext.RequestContext.HttpContext.User != null) 
      { 
       var userSysAdmin = filterContext.RequestContext.HttpContext.User.IsInRole(SysAdminRole) == true; 
       filterContext.ActionParameters["IsSysAdmin"] = userSysAdmin; 
      } 
     } 
    } 
} 

有一個人建議我要去哪裏錯了?如果此人不是系統管理員,則會帶來巨大的好處,它會將他們引導至Home/NoPermissions

謝謝!

+0

可以露出整個類的過濾器? – Aravind

+0

更新後顯示全班。謝謝! – ajtatum

+0

這個帖子可能對你更好地理解https://code.msdn.microsoft.com/ASPNET-MVC-5-Security-And-44cbdb97 – bijayk

回答

1

更新:修復所有問題。 AJ。在這裏,你去... 終於解決了這一問題

using ActionFilterAttribute 
using System.Web.Mvc; 
namespace site_redesign_web.Filters 
{ 
    public class SystemAdminFilter : ActionFilterAttribute 
    { 
     string SysAdminRole = "System Administrator"; 
     public override void OnActionExecuting(ActionExecutingContext filterContext) 
     { 
      if (filterContext.RequestContext.HttpContext.User != null) 
      { 
       var userSysAdmin = filterContext.RequestContext.HttpContext.User.IsInRole(SysAdminRole) == true; 

      if(!userSysAdmin) 
      { 
       filterContext.Result = new RedirectToRouteResult(
        new System.Web.Routing.RouteValueDictionary{ 
        {"controller", "Home"},  
        {"action", "Index"} 
       }); 
      } 
      } 
     } 
    } 
} 

和你控制器應該

[SystemAdminFilter]  // at controller level 
public SomeController : Controller 
{ 

} 

,或者您也可以通過註釋這樣

使用特定 行動
public SomeController : Controller 
{ 
    [SystemAdminFilter]  // at Action level 
    public ActionResult SomeAction() 
    { 
      // perform your actions 
    } 

這將工作,因爲我手動傳遞在用戶他在Application_AuthorizeRequest作用在Global.asax中

protected void Application_AuthorizeRequest(Object sender, EventArgs e) 
{ 
    FormsAuthenticationTicket formsAuthenticationTicket = new FormsAuthenticationTicket("Aravind", true, 30); 
    FormsIdentity formsIdentityId = new FormsIdentity(formsAuthenticationTicket); 
    GenericPrincipal genericPrincipal = new GenericPrincipal(formsIdentityId, new string[] { "SystemUser" }); //TEST with this redirected to Home Index place 
    HttpContext.Current.User = genericPrincipal ; 
} 

下一個測試我做了這個

GenericPrincipal genericPrincipal = new GenericPrincipal(formsIdentityId, new string[] { "System Administrator" }); //TEST with this did not perform an action 
+0

當我試圖實現這個時,我得到:HTTP錯誤404.15 - 未找到 請求過濾模塊被配置爲拒絕查詢字符串太長的請求。該URL最終超過2k長。 – ajtatum

+0

是您在RegisterGlobalFilters方法中的App_Start \ FilterConfig中添加過濾器嗎? – Aravind

+0

是的!真的不知道發生了什麼,這很奇怪!謝謝! – ajtatum

1

由於您正在處理授權,我會擴展AuthorizeAttribute而不是ActionFilterAttribute這是一般模式。您只需要覆蓋一個方法 - HandleUnauthorizedRequest當授權失敗時執行。 AuthorizeAttribute的默認實現已經爲您處理基於角色的授權。

public class SystemAdminAttribute : AuthorizeAttribute 
{ 
    private const string SysAdminRole = "System Administrator"; 

    public SystemAdminFilter() 
    { 
     //this defines the role that will be used to authorize the user: 
     this.Roles = SysAdminRole; 
    } 

    //if user is not authorized redirect to "Home/NoPermissions" page 
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) 
    { 
     if(!filterContext.HttpContext.User.Identity.IsAuthenticated) 
     { 
      base.HandleUnauthorizedRequest(filterContext); 
     } 
     else 
     { 
      filterContext.Result = new RedirectToRouteResult(new 
       RouteValueDictionary(new { controller = "Home", action = "NoPermissions" })); 
     } 
    }   
} 

一旦你的屬性得以實施,相應的裝飾控制器或動作與它:

[SystemAdmin] 
public SysAdminController : Controller 
{ 
} 
+0

看起來不錯,但是當我實現它時,它會將匿名用戶引向NoPermissions頁面。它只有在使用系統管理員權限登錄時纔有效。 – ajtatum

+0

這很奇怪,因爲當用戶沒有通過認證時(這個條件是真的:'!filterContext.HttpContext.User.Identity.IsAuthenticated'),下面這一行被執行:'base.HandleUnauthorizedRequest(filterContext);'應該重定向到登錄頁。你在web.config中有類似的東西嗎?「<錯誤的StatusCode =‘401’重定向=‘〜首頁/ NoPermissions’/>」 –

+0

是的,只要我沒有登錄系統管理員角色,我得到:localhost的頁面無法正常工作 本地主機重定向你太多倍。 – ajtatum