[英]How can Views and ViewModels utilize claims-based authorization in MVC 5?
在我的項目中,我已經實現了具有基於聲明的授權和身份驗證的ASP.NET Identity2.x。 我已添加對聲明授權屬性的支持, 如此處所述 。
以下是我想提出的允許/禁止對員工進行CRUD的主張。
public class ResourceClaimTypes
{
public const string CreateEmployee = "urn:company:Employee:Create";
public const string ReadEmployee = "urn:company:Employee:Read";
public const string UpdateEmployee = "urn:company:Employee:Update";
public const string DeleteEmployee = "urn:company:Employee:Delete";
}
動作如下所示:
[ClaimsAuthorize( ResourceClaimTypes.ReadEmployee )]
public ActionResult Index()
{
return View();
}
我不太了解的是如何在視圖及其視圖模型中使用這些聲明。 例如,有一個用於顯示員工的視圖,它是一個簡單的網格。 然后是用於編輯和創建員工的視圖。
視圖和視圖模型現在應該能夠執行的操作是根據用戶的要求隱藏或顯示“保存/更新/刪除”按鈕。
處理意見:
如果存在ReadEmployee聲明,則Index- >應顯示所有員工,否則該視圖仍應可訪問,但顯示消息“不允許查看員工”。
創建/編輯->用戶仍然應該可以瀏覽這些視圖,但是“創建” /“保存”按鈕應該不可見。
刪除->所有“刪除”按鈕都應隱藏。
最重要的是,視圖應可訪問,但“創建/保存”按鈕應隱藏。
那怎么辦?
*更新/我的解決方案*
這就是我最終這樣做的方式。 按照Derek的建議,我使用了基於操作/資源的身份驗證。 我與ASP.NET Identity一起實現了IUserClaimStore接口,以從數據庫中獲取聲明。
視圖和視圖模型(!)不包含CanRead,CanWrite之類的任何內容! 我正在使用KendoUI,並為按鈕創建了擴展方法。
在擴展方法中,我可以訪問自定義的ResourceAuthorizationManager(請參閱Dominik Baier的博客)。 因此,在創建按鈕時,我可以調用HttpContaxtBase.CheckAccess(...)確定按鈕是否應啟用/可見。
我唯一需要的是一種告訴擴展方法要檢查訪問權限的操作/資源組合的方法。
剃刀示例:
@Html.LinkButton(Action.Create, Resource.Employee)
這是視圖中顯示(或不顯示)顯示“創建”並指向Employee控制器的“創建”視圖的按鈕所需的全部操作。 非常干凈,恕我直言。
您可以在項目的任何地方訪問當前用戶的聲明,視圖也不例外。 只需將當前用戶的身份轉換為claimsIdentity
即可訪問用戶的聲明:
var claims= ((ClaimsIdentity)HttpContext.Current.User.Identity).Claims;
您還可以為此編寫擴展方法:
public static bool CanEdit(this IIdentity identity)
{
return identity.IsAuthenticated
&& identity is ClaimsIdentity
&& ((ClaimsIdentity)identity).HasClaim(x =>
x.Type == "EditClaim" && x.Value == "true");
}
然后,您可以輕松編寫以下代碼:
if(HttpContext.Current.User.Identity.CanEdit())
{
//your code
}
但是,即使您可以直接檢查視圖中的聲明,也可以考慮在控制器中檢查聲明,並通過視圖模型將簡單的true或false值發送到您的視圖,以獲得更好的方法。
由於我們不想將邏輯與視圖混合在一起。 最好在控制器中檢查特權。 考慮一下:
class PrivilegesViewModel
{
public bool CanEdit{get;set;}
public bool CanRead{get;set;}
// and so on
}
class PostViewModel
{
// our model data
public PrivilegesViewModel Privileges{get;set;}
}
在您的控制器中:
public ActionResult Edit(int id)
{
PostViewModel model=_postManager.Get(id);
model.Privileges=new PrivilegesViewModel
{
CanEdit=HttpContext.Current.User.Identity.CanEdit(),
// and so on
}
return View(model);
}
現在在您看來,只需檢查bool值即可;
@if(model.Privileges.CanEdit)
{
// print the button
}
您應該在Thinktecture上查看Dominic Baier的產品,諸如此類。
下面的文章將解釋如何優雅地實現您的期望。
他們在Git Hub倉庫中有例子。
**編輯**
這是您需要遵循的GitHub示例的鏈接。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.