如何使用权限而不是角色来自动化asp.net身份中的用户?

时间:2016-09-18 18:14:58

标签: c# asp.net asp.net-mvc asp.net-identity identity

我正在尝试将Identity用于我正在处理的新应用程序。有关它的最低信息使其难以理解。

根据我对Identity的理解,我可以创建角色(即管理员,超级用户,用户......),并且对于控制器中的每个操作,我可以限制角色是否可以访问操作。这对于典型应用来说是一种不错的方法。但在我的应用程序中,我需要对访问级别进行更深入的控制。我需要能够拥有更多的控制权而不是角色基础的自动化。

在典型的应用程序中,我可以通过控制器中的操作方法[Authorize(Roles = "Admin")]添加此内容,只有拥有Admin的人才能访问它。

但是,我希望能够添加个人权限,并且不确定是否可以使用Identity。 (也许与索赔有关?)

以下是我的想法,我希望能够做到这样的事情

// In a Razor view I want to be able to do this
// Note: HasPermission is not real method, but is something I am posting
//       to explain what I am looking for
if(User.HasPermission("Edit Account")){
 // Show the Edit button
}

if(User.HasPermission("Add Account")){
 // Show the Add Button
}

然后,在我想做的动作方法中能够做到这样的事情。

[Authorize( HasPermission = "Edit Account")]
public ActionResult Edit()
{
    // Handle the edit
}

[Authorize( HasPermission = "Add Account")]
public ActionResult Add()
{
    // Handle the addition
}

该应用程序将拥有许多权限(即编辑帐户,添加帐户,删除帐户....)我将为一个用户分配多个权限。拥有权限Add Account的用户将能够添加帐户。

可以使用开箱即用的身份完成这样的事情吗?如何在不使问题复杂化的情况下开始使用?

2 个答案:

答案 0 :(得分:0)

声明告诉您用户,而不是用户可以执行的操作。例如,它们可能是对用户的名字,电子邮件地址等的声明。可能还会声称用户的角色或他们所属的群组(存在细微差别,但我们暂时忽略它)。例如,可能存在声明用户是会计师和经理的角色声明。

正如您所注意到的,这些声明并未告诉您用户可以执行的操作。可能是会计师可以编辑帐户,但索赔不会告诉您。某种程度上,您必须从角色(和其他声明)转换为权限(如您所说)。

不幸的是,.NET Framework中没有标准组件可以做到这一点。唯一接近的是AzMan,但现在已弃用。

这意味着您有两种选择:

你可以自己角色扮演。这不是太困难。基本上,您需要一个在角色和任务之间具有多对多关系的数据结构,以及任务与单个细粒度权限之间的多对多关系。阿兹曼模型可以成为一个很好的灵感来源。

许多人采用的替代方案,对于简单的应用程序,可能已经足够好了,就是对应用程序中的角色进行硬编码。这就是[Authorize(Roles = "Accountant")]的用武之地。显然,只要业务组织发生变化,这个模型就需要重新编译,但如果不经常发生这种情况,那就可以了。

不幸的是,没有更好的答案。

答案 1 :(得分:0)

您可以通过向基础添加权限概念来扩展Identity工作流。您应该关注的最重要的事情是当前模型与新增功能之间的关系。我在我的最新项目中这样做并将其作为开源Permission Extension to Identity 2 membership system here发布。 您可以阅读自述文件,也可以自己提出问题或自己扩展库。

作为一个简短的例子,您可以像这样使用它:

第一种方法:

// GET: /Manage/Index
[AuthorizePermission(Name = "Show_Management", Description = "Show the Management Page.")]
public async Task<ActionResult> Index(ManageMessageId? message)
{
    //...
}

第二种方法:

// GET: /Manage/Users
public async Task<ActionResult> Users()
{
    if (await HttpContext.AuthorizePermission(name: "AllUsers_Management", description: "Edit all of the users information."))
    {
        return View(db.GetAllUsers());
    }
    else if (await HttpContext.AuthorizePermission(name: "UnConfirmedUsers_Management", description: "Edit unconfirmed users information."))
    {
        return View(db.GetUnConfirmedUsers());
    }
    else
    {
        return View(new List<User>());
    }
}