0

在我的项目中,我使用基于声明的授权和身份验证实现了 ASP.NET Identity 2.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 声明,则索引 ->应显示所有员工,否则该视图仍应可访问,但会显示消息“无查看员工的权限”。

创建/编辑 ->用户应该仍然能够导航到这些视图,但“创建”/“保存”按钮不应该是可见的。

删除 ->应隐藏所有“删除”按钮。

底线是,视图应该是可访问的,但创建/保存按钮应该被隐藏。

怎么可能呢?

*更新/我的解决方案*

这就是我最终做到的方式。按照 Derek 的建议,我使用了基于操作/资源的身份验证。除了 ASP.NET Identity,我还实现了 IUserClaimStore 接口以从数据库中获取声明。

视图和视图模型 (!) 不包含 CanRead、CanWrite 之类的任何内容! 我正在使用 KendoUI 并为按钮创建了一个扩展方法。

在扩展方法中,我可以访问自定义 ResourceAuthorizationManager(参见 Dominik Baier 的博客)。所以在创建按钮时,我可以调用 HttpContaxtBase.CheckAccess(...) 来确定按钮是否应该启用/可见。

我唯一需要的是一种方法来告诉扩展方法要检查访问的操作/资源组合。

剃刀示例:

@Html.LinkButton(Action.Create, Resource.Employee)

这就是视图中显示(或不显示)“创建”按钮并指向员工控制器的创建视图所需的全部内容。很干净,恕我直言。

4

2 回答 2

1

您可以在项目中的任何地方访问当前用户的声明,视图也不例外。只需将当前用户的身份转换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
}

但即使您可以直接检查视图中的声明,考虑检查控制器中的声明,并通过视图模型将简单的真或假值发送到您的视图以获得更好的方法。

因为我们不想将我们的逻辑与视图混合。最好在控制器中检查权限。考虑一下:

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

现在在您看来,只需检查布尔值;

@if(model.Privileges.CanEdit)
{
    // print the button
}
于 2015-08-28T10:39:55.527 回答
1

您应该查看 Thinktecture 的 Dominic Baier 的产品,以获得类似的东西。

下面的文章将解释如何非常优雅地实现您的目标。

http://leastprivilege.com/2014/06/24/resourceaction-based-authorization-for-owin-and-mvc-and-web-api/

他们在 Git Hub 存储库中有示例。

** 编辑 **

这是您需要遵循的 GitHub 示例的链接。

https://github.com/IdentityModel/Thinktecture.IdentityModel/tree/master/samples/OWIN/ResourceAuthorization/Chinook

于 2015-08-28T14:44:54.303 回答