6

我目前正在編寫一個Admin MVC 3站點,並且每個用戶只能訪問站點的某些部分。asp.net MVC 3將AuthorizeAttribute應用到區域

我的網站的區域與用戶角色相同,所以我想要做的是將AuthorizeAttribute放置在每個區域上,並使用該區域的名稱作爲角色中的參數。

到目前爲止,當我對每個區域的檢查進行硬編碼時,我已經得到了這個工作,但我想循環遍歷所有區域並應用Authorize過濾器。 (我用這個作爲我的自定義FilterProvider - http://www.dotnetcurry.com/ShowArticle.aspx?ID=578

到目前爲止我的代碼(「GCM」是我的領域之一,也是一個角色):

public static void RegisterGlobalFilters(GlobalFilterCollection filters) 
{ 
    filters.Add(new HandleErrorAttribute()); 
    // for all controllers, run AdminAuthorizeAttribute to make sure they're at least logged in 
    filters.Add(ObjectFactory.GetInstance<AdminAuthorizeAttribute>()); 

    AdminAuthorizeAttribute gcmAuthroizeAttribute = ObjectFactory.GetInstance<AdminAuthorizeAttribute>(); 
    gcmAuthroizeAttribute.Roles = "Gcm"; 

    var provider = new FilterProvider(); 
    provider.Add(
     x => 
     x.RouteData.DataTokens["area"] != null && x.RouteData.DataTokens["area"].ToString() == "Gcm" 
      ? gcmAuthroizeAttribute 
      : null); 
    FilterProviders.Providers.Add(provider); 
} 

有誰知道以獲得我的應用程序的所有領域,所以我可以循環遍歷它們,而不是對每個區域進行硬編碼?

或者如果任何人有更好的想法如何授權每個區域,這將不勝感激。

感謝您的幫助 Saan

回答

-1

當我正在調查一個單獨的問題,我碰到How to pass parameters to a custom ActionFilter in ASP.NET MVC 2?

該屬性例如可以改變檢查電流控制的區域。

public class CustomAuthorizeAttribute : AuthorizeAttribute 
{ 
    public override void OnAuthorization(AuthorizationContext filterContext) 
    { 
     RouteData routeData = filterContext.RouteData; 

     // check if user is allowed on this page 
     if (SessionFactory.GetSession().Contains(SessionKey.User)) 
     { 
      User user = (User)SessionFactory.GetSession().Get(SessionKey.User); 
      string thisArea = routeData.DataTokens["area"].ToString(); 

      // if the user doesn't have access to this area 
      if (!user.IsInRole(thisArea)) 
      { 
       HandleUnauthorizedRequest(filterContext); 
      } 
     } 

     // do normal OnAuthorization checks too 
     base.OnAuthorization(filterContext); 
    } 
} 

我然後我的自定義授權屬性應用到在Global.asax中這樣所有的控制器:

public static void RegisterGlobalFilters(GlobalFilterCollection filters) 
{ 
    filters.Add(new HandleErrorAttribute()); 
    // for all controllers, run CustomAuthorizeAttribute to make sure they're at logged in and have access to area 
    filters.Add(ObjectFactory.GetInstance<CustomAuthorizeAttribute>()); 
} 

感謝所有誰回答

Saan

+1

**警告:這不是安全的做法。**我一直在看這個相同的區域,發現這不是一個明智的做法。區域是一個路由概念,但是即使未指定區域,控制器也可以被發現並被拾取**。 [Levi在這裏解釋](http://stackoverflow.com/questions/2319157/how-can-we-set-authorization-for-a-whole-area-in-asp-net-mvc/2320419#2320419) – Quango 2013-01-25 08:18:31

0

這是一個授權的實例屬性來覆蓋我已經建立。我需要我的授權功能來支持會員輪船的類型,因此您可能不想過度使用這些功能的內部工作,但是AuthorizeCore是主邏輯發生的地方。在我的情況下,我正在對照實體datacontext進行檢查。

用法:

[AjaxAuthorize(AjaxRole = "Administrators")] 
public JsonResult SaveAdministrativeUser(v....) 

代碼:

public class AjaxAuthorizeAttribute : AuthorizeAttribute 
    { 
     private class HttpAuthorizeFailedResult : ActionResult 
     { 
      public override void ExecuteResult(ControllerContext context) 
      {     
       // Set the response code to 403. Membership.Provider.Name == "UnitArchiveMembershipProvider" 
       context.HttpContext.Response.StatusCode = context.HttpContext. User.Identity is WindowsIdentity ? 401 : 403; 
      } 
     } 

     public string AjaxRole { get; set;} 

     public AjaxAuthorizeAttribute() 
     { 
      AjaxRole = "Users"; 
     } 

     protected override bool AuthorizeCore(HttpContextBase httpContext) 
     { 
      if (string.IsNullOrEmpty(MvcApplication.Config.DBSettings.Database)) 
      { 
       return true; 
      } 

      //When authorize parameter is set to false, not authorization should be performed. 
      UnitArchiveData db = DataContextFactory.GetWebRequestScopedDataContext<UnitArchiveData>(MvcApplication.Config.DBSettings.GetConnectionString());    


      if (httpContext.User.Identity.IsAuthenticated) 
      { 
       login_data user = db.login_datas.Where(n => n.EmailAddress == httpContext.User.Identity.Name).FirstOrDefault(); 
       if (user != null) 
       { 
        return user.cd_login_role.RoleName == "Administrators" || user.cd_login_role.RoleName == AjaxRole; 
       } 
      } 

      return false; 

     } 

     protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) 
     { 
      if (filterContext.RequestContext.HttpContext.Request.IsAjaxRequest()) 
      { 
       //Ajax request doesn't return to login page, it just returns 403 error. 
       filterContext.Result = new HttpAuthorizeFailedResult(); 
      } 
      else 
       base.HandleUnauthorizedRequest(filterContext); 
     } 
    } 
+0

謝爾蓋你好。感謝您的迴應 - 但我已經創建了我的自定義授權屬性,並且它工作正常。我只需要能夠在每個區域傳遞適當的角色。我不想在每個控制器上放置屬性。我正在尋找可以在有人添加新區域時自動設置的內容。 – Saan 2011-05-16 16:33:04

+0

是的,看看我是如何做到這一點。 AjaxRole變量被傳遞到自定義的AuthorizeAttribte中。自動可能是一個艱難的,但添加一個[AjaxAuthorize(AjaxRole =「管理員」)]功能標題並不難,並解決您的問題。 – 2011-05-16 16:44:25

+0

但它的確意味着任何向該項目添加代碼的人(並且有些人將成爲第三方開發人員)都需要確保將正確的Authorize屬性添加到Controller中。我正在尋找的是一種確保無論使用何種正確授權的方式。 – Saan 2011-05-16 20:23:04

2

你,你可以爲每個區域一個基本的控制器,並把授權屬性在基類。這樣你就可以爲每個區域的基礎控制器傳遞區域參數。