2012-10-09 51 views
0

我正在尋找一個在控制器級別加載和授權資源的實現/示例。我正在尋找與load_and_authorize_resource相同的功能,在cancan寶石紅寶石軌道上。將load_and_authorize_resource從rails導入mvc .net

有沒有人遇到過/有一個例子如何使用Mvc .Net屬性實現類似的東西?

謝謝!

的load_and_authorize_resource行爲

隨着軌,控制器和模型名稱由慣例相銜接。 load_and_authorize_resource這個屬性就是有利的。當需要資源實例的操作被擊中時,load_and_authorize_resource驗證是否可以訪問資源的實例。如果可以的話,它會將它加載到一個實例變量中,如果它不能,它將返回一個404或任何你配置了該屬性的錯誤行爲。

例如,如果我有資源圖片,並且只有擁有特定圖片的用戶纔可以編輯圖片的名稱。

所以我們會有一個Edit動作,顯然它會有一個你想要編輯的圖片的pictureId。 load_and_authorize_resource將驗證當前上下文/用戶是否有權訪問資源。

Here是一個小模塊的視頻介紹。

+0

對於那些不熟悉的RoR你能簡單總結一下這個插件提供的功能? –

+0

已更新。讓我知道如果你有任何問題 – Karan

回答

2

我不知道ASP.NET MVC的這種插件的存在。要模仿它的功能,你可以儘管編寫自定義Authorize屬性:

public class LoadAndAuthorizeResourceAttribute : AuthorizeAttribute 
{ 
    private class ModelDescriptor 
    { 
     public string Name { get; set; } 
     public Type ModelType { get; set; } 
    } 

    private const string ModelTypeKey = "__ModelTypeKey__"; 
    public override void OnAuthorization(AuthorizationContext filterContext) 
    { 
     var parameters = filterContext.ActionDescriptor.GetParameters(); 
     if (parameters.Length > 0) 
     { 
      // store the type of the action parameter so that we could access it later 
      // in the AuthorizeCore method 
      filterContext.HttpContext.Items[ModelTypeKey] = new ModelDescriptor 
      { 
       Name = parameters[0].ParameterName, 
       ModelType = parameters[0].ParameterType, 
      }; 
     } 
     base.OnAuthorization(filterContext); 
    } 

    protected override bool AuthorizeCore(HttpContextBase httpContext) 
    { 
     var authorized = base.AuthorizeCore(httpContext); 
     if (!authorized) 
     { 
      // the user is not authenticated or authorized => no need to continue 
      return false; 
     } 

     // get the currently authenticated username 
     string username = httpContext.User.Identity.Name; 

     // get the id of the resource that he is trying to manipulate 
     // the id should be sent either as part of the query string or the routes 
     string id = httpContext.Request.RequestContext.RouteData.Values["id"] as string; 

     // get the action param type 
     var modelDescriptor = httpContext.Items[ModelTypeKey] as ModelDescriptor; 

     if (modelDescriptor == null) 
     { 
      throw new InvalidOperationException("The controller action that was decorated with this attribute must take a model as argument"); 
     } 

     // now load the corresponding entity from your database given the 
     // username, id and type 
     object model = LoadModel(id, username, modelDescriptor.ModelType); 

     if (model == null) 
     { 
      // the model that satisfies the given criteria was not found in the database 
      return false; 
     } 

     httpContext.Request.RequestContext.RouteData.Values[modelDescriptor.Name] = model; 

     return true; 
    } 

    private object LoadModel(string id, string username, Type modelType) 
    { 
     // TODO: depending on how you are querying your database 
     // you should load the corresponding model here or return null 
     // if not found 
     throw new NotImplementedException(); 
    } 
} 

,現在你可以有一個與此屬性裝飾控制器動作:

[LoadAndAuthorizeResource] 
public ActionResult Edit(Picture model) 
{ 
    ... if we get that far the user is authorized to modify this model 
} 
+0

甜!謝謝!在將來的某個時候,我可能會嘗試將其作爲一個NuGet包,我非常肯定它對於其他項目會非常有用:) – Karan