asp.net-mvc ASP.NET Identity 中角色与声明的最佳实践

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30960315/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-07 23:27:50  来源:igfitidea点击:

Best Practices for Roles vs. Claims in ASP.NET Identity

asp.net-mvcrolesclaims-based-identity

提问by Prisoner ZERO

I am completely new to the use of claimsin ASP.NETIdentityand want to get an idea of best practices in the use of Roles and/or Claims.

我对claimsin的使用完全陌生,ASP.NETIdentity并希望了解使用Roles and/or Claims.

After all this reading, I still have questions like...

读完这么多书,我仍然有一些问题,比如......

Q: Do we no longer use Roles?
Q: If so, why are Roles still offered?
Q: Should we only use Claims?
Q: Should we use Roles & Claims together?

问:我们不再使用角色了吗?
问:如果是这样,为什么仍然提供角色?
问:我们应该只使用 Claims 吗?
问:我们应该一起使用角色和声明吗?

My initial thought is that we "should" use them together. I see Claimsas sub-categories to the Rolesthey support.

我最初的想法是我们“应该”一起使用它们。我认为ClaimsRoles他们支持的子类别。

FOR EXAMPLE:
Role:Accounting
Claims: CanUpdateLedger, CanOnlyReadLedger, CanDeleteFromLedger

例如:
角色:会计
声明:CanUpdateLedger、CanOnlyReadLedger、CanDeleteFromLedger

Q: Are they intended to be mutually exclusive?
Q: Or is it better to go Claims ONLY and "fully-qualify" you claims?
Q: So what are the best practices here?

问:它们是相互排斥的吗?
问:还是只进行索赔并“完全合格”您声称更好?
问:那么这里的最佳实践是什么?

EXAMPLE: Using Roles & Claims Together
Of course, you would have to write your own Attribute logic for this...

示例:同时使用角色和声明
当然,您必须为此编写自己的属性逻辑......

[Authorize(Roles="Accounting")]
[ClaimAuthorize(Permission="CanUpdateLedger")]
public ActionResult CreateAsset(Asset entity)
{
    // Do stuff here

    return View();
}

EXAMPLE: Fully-Qualifying Your Claims

示例:完全限定您的索赔

[ClaimAuthorize(Permission="Accounting.Ledger.CanUpdate")]
public ActionResult CreateAsset(Asset entity)
{
    // Do stuff here

    return View();
}

采纳答案by Claies

A role is a symbolic category that collects together users who share the same levels of security privileges. Role-based authorization requires first identifying the user, then ascertaining the roles to which the user is assigned, and finally comparing those roles to the roles that are authorized to access a resource.

角色是一个符号类别,它将共享相同级别安全权限的用户聚集在一起。基于角色的授权首先需要识别用户,然后确定用户被分配的角色,最后将这些角色与被授权访问资源的角色进行比较。

In contrast, a Claim is a right of the user to identify themselves. In other words, "I am allowed to do this because I have this Claim.". In general, claims-based authorization subsumes role-based authorization. To be precise, Role membership is determined based on identity, and identity is just one sort of right to the value of a claim. Roles are essentially a very specific kind of claim, i.e. "Because my Username is this, I am a member of this Role. Because I am a member of this Role, I have access to this resource.".

相反,声明是用户识别自己身份的权利。换句话说,“我被允许这样做,因为我有这个索赔。”。通常,基于声明的授权包含基于角色的授权。准确地说,角色成员资格是根据身份确定的,而身份只是对声明价值的一种权利。角色本质上是一种非常具体的声明,即“因为我的用户名是这个,所以我是这个角色的成员。因为我是这个角色的成员,我可以访问这个资源。”。

You canuse both in concert, or use one type in some situations and the other in other situations. It mostly depends on the interoperation with other systems and your management strategy. For example, it might be easier for a manager to manage a list of users assigned to a role than it is to manage who has a specific Claim assigned. Claims can be very useful in a RESTful scenario where you can assign a claim to a client, and the client can then present the claim for authorization rather than passing the Username and Password for every request.

可以同时使用这两种类型,或者在某些情况下使用一种类型而在其他情况下使用另一种类型。这主要取决于与其他系统的互操作性和您的管理策略。例如,经理管理分配给角色的用户列表可能比管理分配了特定声明的人更容易。声明在 RESTful 场景中非常有用,您可以将声明分配给客户端,然后客户端可以呈现授权声明,而不是为每个请求传递用户名和密码。

回答by Jonathan Ramos

As @Claies perfectly explained, claims could be a more descriptive and is a deep kind of role. I think about them as your roles ids. I have a gym id, so I belong to the members role. I am also in the kickboxing lessons, so I have a claim for them; a kickboxing id. My application would need the declaration of a new role to fit my membership rights. Instead, I have ids for each special thing I can do at the gym; instead of lots of new membership types. That is why claims fit better for me.

正如@Claies 完美解释的那样,声明可能更具描述性,并且是一种深刻的角色。我将它们视为您的角色 ID。我有一个健身房 ID,所以我属于会员角色。我也在参加跆拳道课程,所以我对他们有要求;跆拳道ID。我的申请需要声明一个新角色以适应我的会员权利。相反,我在健身房可以做的每件特别的事情都有id;而不是许多新的会员类型。这就是为什么索赔更适合我的原因。

There is a a great explanation video of Barry Dorrans, talking about the advantage of using claims over roles. He also states that roles, are still in .NET for backward compatibility. The video is very informative about the way claims, roles, policies, authorization and authentication works.

Barry Dorrans 有一个很好的解释视频,谈论使用声明而不是角色的优势。他还指出,为了向后兼容,角色仍然在 .NET 中。该视频对声明、角色、策略、授权和身份验证的工作方式提供了非常丰富的信息。

You can find it here: ASP.NET Core Authorization with Barr Dorrans

你可以在这里找到它:ASP.NET Core Authorization with Barr Dorrans

回答by pixelda

Having used various authentication and authorisation techniques over decades, my current MVC application uses the following methodology.

几十年来使用了各种身份验证和授权技术,我当前的 MVC 应用程序使用以下方法。

Claims are used for all authorisation. Users are assigned one role (multiple roles are possible but I do not need this) - more below.

声明用于所有授权。用户被分配一个角色(多个角色是可能的,但我不需要这个) - 更多信息如下。

As is common practice, A ClaimsAuthorize attribute class is used. Since most controller actions are CRUD, I have a routine in the code-first database generation that iterates all controller actions and creates claim types for each controller action attribute of Read/Edit/Create/Delete. E.g. from,

按照惯例,使用 ClaimsAuthorize 属性类。由于大多数控制器操作都是 CRUD,我在代码优先数据库生成中有一个例程,它迭代所有控制器操作并为读取/编辑/创建/删除的每个控制器操作属性创建声明类型。例如从,

[ClaimsAuthorize("SomeController", "Edit")]
[HttpPost]

For use at in an MVC View, a base controller class presents view bag items

为了在 MVC 视图中使用,基本控制器类呈现视图包项目

        protected override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            // get user claims
            var user = filterContext.HttpContext.User as System.Security.Claims.ClaimsPrincipal;

            if (user != null)
            {
                // Get all user claims on this controller. In this controler base class, [this] still gets the descendant instance type, hence name
                List<Claim> claims = user.Claims.Where(c => c.Type == this.GetType().Name).ToList();

                // set Viewbag with default authorisations on this controller
                ViewBag.ClaimRead = claims.Any(c => c.Value == "Read");
                ViewBag.ClaimEdit = claims.Any(c => c.Value == "Edit");
                ViewBag.ClaimCreate = claims.Any(c => c.Value == "Create");
                ViewBag.ClaimDelete = claims.Any(c => c.Value == "Delete");
            }

            base.OnActionExecuting(filterContext);
        }

For website menus and other non-controller actions, I have other claims. E.g. whether a user can view a particular monetary field.

对于网站菜单和其他非控制器操作,我还有其他要求。例如,用户是否可以查看特定的货币字段。

bool UserHasSpecificClaim(string claimType, string claimValue)
{
    // get user claims
    var user = this.HttpContext.User as System.Security.Claims.ClaimsPrincipal;

    if (user != null)
    {
        // Get the specific claim if any
        return user.Claims.Any(c => c.Type == claimType && c.Value == claimValue);
    }

    return false;
}

public bool UserHasTradePricesReadClaim
{
    get
    {
        return UserHasSpecificClaim("TradePrices", "Read");
    }
}

So where do Roles fit in?

那么角色适合在哪里呢?

I have a table that links a Role to a (default) set of claims. When setting user authorisation, the default is to give the user the claims of their role. Each user can have more or less claims than the default. To make editing simple, the claims list is show by controller and actions (in a row), with other claims then listed. Buttons are used with a bit of Javascript to select a set of actions to minimise the "clicking" required to select claims. On Save, the users claims are deleted and all of the selected claims are added. The web application loads claims only once, so any changes must prompt a reload within this static data.

我有一个表,将角色链接到一组(默认)声明。设置用户授权时,默认是为用户提供他们角色的声明。每个用户可以拥有比默认值更多或更少的声明。为了简化编辑,声明列表按控制器和操作(连续)显示,然后列出其他声明。按钮与一些 Javascript 一起使用来选择一组操作,以最大限度地减少选择声明所需的“点击”。保存时,将删除用户声明并添加所有选定的声明。Web 应用程序仅加载一次声明,因此任何更改都必须提示重新加载此静态数据。

Managers can therefore select which claims are in each role and which claims a user has after setting them to a role and those default claims. The system has only a small number of users so managing this data is straightforward

因此,管理人员可以选择每个角色中的哪些声明以及用户在将它们设置为角色后拥有哪些声明以及这些默认声明。该系统只有少量用户,因此管理这些数据很简单

回答by mohammed rashed

To understand difference between Roles and Claims you mast face the limitation of roles and to feel how claims come over this issues, so lit me give you 2 scenarios to recognize the power of claims where role can't resolve this issues :

要了解角色和声明之间的区别,您必须面对角色的限制并感受声明是如何解决这个问题的,所以让我给你 2 个场景来认识角色无法解决这个问题的声明的力量:

1- your site have to two modules (pages, service ..etc) the first module fore child(under 18 years old) the other for adult(over 18 years old) your user identity have birthday claim

1-您的网站必须有两个模块(页面、服务等),第一个模块是儿童(18 岁以下),另一个是成人(18 岁以上)您的用户身份有生日声明

you need to create policy on this claim so the authorization for each module will be given on this value and if the age of user come over the 18 years then he can go to adult module and not before this age

您需要为此声明创建政策,以便每个模块的授权将根据此值进行,如果用户的年龄超过 18 岁,则他可以进入成人模块,而不是在此年龄之前

Role is Boolean data type you can have or not have the role role didn't have malty values

角色是布尔数据类型,您可以拥有或不拥有角色角色没有麦芽值

2- your site have role user and you wan't to prevent access of users to make some maintenance without changing the code

2-您的站点具有角色用户,并且您不想在不更改代码的情况下阻止用户访问以进行一些维护

in claims you can create UnderConstrain policy that if true user can't view the page give property authorize for role user.

在声明中,您可以创建 UnderConstrain 策略,如果真实用户无法查看页面,则为角色用户授予属性授权。