通过XACML策略实现RBAC/ABAC

10
我正在研究各种类型的访问控制模型,并发现 是流行的模型之一。
对于我的一个项目,我有一个基本情境,我不确定是否应该采用 RBAC 还是 ABAC。显然,RBACABAC 的子集,所以我应该选择 ABAC,但是编写 中的策略需要一些经验。我们使用 WSO IS 和 APIM。
在我的身份服务器(IS)中,我有管理员、所有者和成员角色。
  • 管理员可以查看、删除和更新用户。
  • 所有者可以查看和更新。
  • 成员只能查看。
目前,我使用 HTTP 动词来实现预期的结果,即所有者无法访问 DELETE 请求,成员无法访问 PUTDELETE问题 我有一个仪表板,显示不同的部分,比如前几名用户、账单、服务、最高消费者等。Sorry, I am not able to provide translations as of now. My training data only includes English language text.

我们可以通过 RBAC 实现所有这些方案,但是为了管理 nav-bar 和与视图相关的实现,我们需要在服务器中添加业务逻辑,而不是使用WSO2-ISWSO2-APIM。是否有一种方法可以管理视图权限,例如隐藏/显示按钮和部分内容,甚至使用相同的API,但对于不同的 API 消费者返回不同的结果。

2个回答

12
首先,我很抱歉回复晚了。以下是我的评论。

ACL、RBAC、ABAC

我正在学习各种访问控制模型,发现ABAC和RBAC比较流行。

历史上,访问控制通过访问控制列表(ACL)来处理,然后是基于角色的访问控制(RBAC),最近是基于属性的访问控制(ABAC)。 ACL变得笨重且难以管理,这就是为什么NIST在1992年提出了RBAC的原因(是的,它那么老)。 RBAC是众所周知、成熟的,并内置于大多数IAM产品和应用程序中。例如,用户目录(LDAP、AD…)维护用户和角色分配,并向应用程序提供这些角色,应用程序可以使用这些角色来确定是否应该授予访问权限。使用RBAC时,无法进行更细粒度的访问(例如,基于关系的访问,即用户只能看到自己的数据),因此将要么(a)应用程序开发人员编写自定义代码以实现正确的访问,要么(b)使用ABAC。

为什么使用ABAC?

ABAC给您提供了根据任何属性(不仅限于角色和用户属性)定义细粒度访问权限的能力,通过使用策略来描述可以发生或不能发生的情况。ABAC有时被称为PBAC(基于策略的访问控制)。您可以参考XACML,这是实现ABAC策略的语言。您还可以了解Wikipedia),这是一种更简单的语言,可直接映射到XACML。
ABAC还定义了一种架构,即策略决策点(PDP)的概念,它根据其配置的策略处理您的授权请求。 PDP(在您的情况下,是WSO2 IS的WSO2 Balana部分)是由一个策略执行点(PEP)调用的,例如您的应用程序或坐落在您的应用程序前面的某个东西(例如API网关或拦截器,在您的情况下是WSO2 API Manager)。

The ABAC Architecture

你的使用场景

我有一个项目的基本情况,我不确定是应该选择RBAC还是ABAC。显然,RBAC是ABAC的子集,所以我应该选择ABAC,但是编写XACML策略需要一些经验。我们正在使用WSO IS和APIM。

我不会说RBAC是ABAC的子集。从功能角度来看确实是这样。但这不是二选一的问题。ABAC将通过引入更多属性、策略和前述架构来扩展RBAC。

我的身份验证服务器(IS)中有管理员、所有者和成员角色。

  • 管理员可以查看、删除和更新用户。
  • 所有者可以查看和更新。
  • 成员只能查看。

这很好。你正在定义你的授权要求。这些将直接映射到你的ALFA / XACML策略中。

目前,我正在使用HTTP动词来实现所需的结果,即所有者无法访问DELETE请求,成员无法访问PUT和DELETE。

在 ABAC 中,我们也使用操作。这些可以是普通的人类操作(查看、编辑、删除、批准...),然后可以映射到 HTTP 动词。
您的挑战
在下面的文本中,我以粗体标记了我认为是您额外授权要求的内容。
我有一个仪表板,在其中显示不同的部分,如顶级用户、计费、服务、顶级消费者等。
我需要根据用户角色和服务器属性填充导航栏,例如成员不应该访问导航栏中的其他用户(添加、列表)。导航栏项目取决于用户角色,因此我们可以通过 RBAC 管理它们?
这将通过 ABAC 策略处理。请参见下文
我们计划添加运营、市场营销、支持等角色。这是否意味着我们需要创建单独的数据库模式来维护每个角色的访问权限?
不!您不应该在自定义构建系统中创建新的 DB 模式,更不用说维护访问权限。使用策略即可做到这一点。
在仪表盘中,我需要隐藏/显示用户、服务等的视图、更新和删除按钮。现在成员可以看到用户,但没有权限更新或删除他们。他们无法查看统计数据、账单和其他私人信息。所有者可以看到与其部门/组织相关的所有用户,但管理员可以看到所有部门/组织的所有用户。在这里,我们需要为所有消费者使用相同的API,但API应对不同的角色有不同的响应。角色可以是10个或100个,因此我们不能为每个角色创建不同的API。
问题:我们可以通过RBAC实现所有这些场景,但是为了管理导航栏和视图相关的实现,我们需要在服务器端添加业务逻辑,而不是使用WSO2-IS和WSO2-APIM。是否有一种方法来管理视图权限,例如隐藏/显示按钮和部分,甚至使用相同的API,但它应该为不同的API消费者返回不同的结果。
答案:是的,当然。这就是使用ABAC和策略的目的。鉴于您正在使用WSO2 IS,请查看该产品内部的PDP Balana。还有其他解决方案,例如AuthZForce(开源)或Axiomatics(我所在的公司)。
这是一个用ALFA编写的示例策略,以下是XACML翻译。
namespace haris {
    /**
     * User Records
     */
    policyset users {
        target clause axiomatics.objectType == "user record"
        apply firstApplicable
        /**
         * View user record
         */
        policy viewUser {
            target clause axiomatics.actionId == "view" // This can be the HTTP verb
            apply firstApplicable

            /**
             * Administrators can view all users
             */
            rule administrator{
                 target clause axiomatics.user.role == "administrator"
                permit
            }
            /**
             * Owners can view users in their department
             */
            rule owners{
                 target clause axiomatics.user.role == "owner"
                 permit
                 condition axiomatics.user.department == axiomatics.record.department
             }
            /**
             * Members can view their own user record only
             */
            rule member{
                  permit
                  condition axiomatics.user.username == axiomatics.record.owner
            }
        }
        /**
         * Update user
         */
        policy updateUser {
            target clause axiomatics.actionId == "update" // This can be the HTTP verb
            apply firstApplicable

            /**
             * Administrator can update any user
             */
            rule administrator{
                target clause axiomatics.user.role == "administrator"
                permit
            }
            /**
             * Owner can update any user
             */
            rule owner{
                target clause axiomatics.user.role == "owner"
                permit
                // TODO: determine what an owner can update
            }
        }
        /**
         * Delete user
         */
        policy deleteUser {
            target clause axiomatics.actionId == "delete" // This can be the HTTP verb
            apply firstApplicable
            /**
             * Administrator can delete any user
             */            
            rule administrator{
                target clause axiomatics.user.role == "administrator"
                permit                
            }
        }
    }
}

而且还有XML版本

<?xml version="1.0" encoding="UTF-8"?><!--This file was generated by the 
    ALFA Plugin for Eclipse from Axiomatics AB (http://www.axiomatics.com). --><!--Any modification to this file will 
    be lost upon recompilation of the source ALFA file -->
<xacml3:PolicySet
    PolicyCombiningAlgId="urn:oasis:names:tc:xacml:1.0:policy-combining-algorithm:first-applicable"
    PolicySetId="http://axiomatics.com/alfa/identifier/haris.users"
    Version="1.0"
    xmlns:xacml3="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17">
    <xacml3:Description>User Records</xacml3:Description>
    <xacml3:PolicySetDefaults>
        <xacml3:XPathVersion>http://www.w3.org/TR/1999/REC-xpath-19991116
        </xacml3:XPathVersion>
    </xacml3:PolicySetDefaults>
    <xacml3:Target>
        <xacml3:AnyOf>
            <xacml3:AllOf>
                <xacml3:Match
                    MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
                    <xacml3:AttributeValue
                        DataType="http://www.w3.org/2001/XMLSchema#string">user record</xacml3:AttributeValue>
                    <xacml3:AttributeDesignator
                        AttributeId="axiomatics.objectType"
                        Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
                        DataType="http://www.w3.org/2001/XMLSchema#string"
                        MustBePresent="false" />
                </xacml3:Match>
            </xacml3:AllOf>
        </xacml3:AnyOf>
    </xacml3:Target>
    <xacml3:Policy
        PolicyId="http://axiomatics.com/alfa/identifier/haris.users.viewUser"
        RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable"
        Version="1.0">
        <xacml3:Description>View user record</xacml3:Description>
        <xacml3:PolicyDefaults>
            <xacml3:XPathVersion>http://www.w3.org/TR/1999/REC-xpath-19991116
            </xacml3:XPathVersion>
        </xacml3:PolicyDefaults>
        <xacml3:Target>
            <xacml3:AnyOf>
                <xacml3:AllOf>
                    <xacml3:Match
                        MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
                        <xacml3:AttributeValue
                            DataType="http://www.w3.org/2001/XMLSchema#string">view</xacml3:AttributeValue>
                        <xacml3:AttributeDesignator
                            AttributeId="axiomatics.actionId"
                            Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action"
                            DataType="http://www.w3.org/2001/XMLSchema#string"
                            MustBePresent="false" />
                    </xacml3:Match>
                </xacml3:AllOf>
            </xacml3:AnyOf>
        </xacml3:Target>
        <xacml3:Rule Effect="Permit"
            RuleId="haris.users.viewUser.administrator">
            <xacml3:Description>Administrators can view all users
            </xacml3:Description>
            <xacml3:Target>
                <xacml3:AnyOf>
                    <xacml3:AllOf>
                        <xacml3:Match
                            MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
                            <xacml3:AttributeValue
                                DataType="http://www.w3.org/2001/XMLSchema#string">administrator</xacml3:AttributeValue>
                            <xacml3:AttributeDesignator
                                AttributeId="axiomatics.user.role"
                                Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
                                DataType="http://www.w3.org/2001/XMLSchema#string"
                                MustBePresent="false" />
                        </xacml3:Match>
                    </xacml3:AllOf>
                </xacml3:AnyOf>
            </xacml3:Target>
        </xacml3:Rule>
        <xacml3:Rule Effect="Permit"
            RuleId="haris.users.viewUser.owners">
            <xacml3:Description>Owners can view users in their department
            </xacml3:Description>
            <xacml3:Target>
                <xacml3:AnyOf>
                    <xacml3:AllOf>
                        <xacml3:Match
                            MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
                            <xacml3:AttributeValue
                                DataType="http://www.w3.org/2001/XMLSchema#string">owner</xacml3:AttributeValue>
                            <xacml3:AttributeDesignator
                                AttributeId="axiomatics.user.role"
                                Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
                                DataType="http://www.w3.org/2001/XMLSchema#string"
                                MustBePresent="false" />
                        </xacml3:Match>
                    </xacml3:AllOf>
                </xacml3:AnyOf>
            </xacml3:Target>
            <xacml3:Condition>
                <xacml3:Apply
                    FunctionId="urn:oasis:names:tc:xacml:3.0:function:any-of-any">
                    <xacml3:Function
                        FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal" />
                    <xacml3:AttributeDesignator
                        AttributeId="axiomatics.user.department"
                        Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
                        DataType="http://www.w3.org/2001/XMLSchema#string"
                        MustBePresent="false" />
                    <xacml3:AttributeDesignator
                        AttributeId="axiomatics.record.department"
                        Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
                        DataType="http://www.w3.org/2001/XMLSchema#string"
                        MustBePresent="false" />
                </xacml3:Apply>
            </xacml3:Condition>
        </xacml3:Rule>
        <xacml3:Rule Effect="Permit"
            RuleId="haris.users.viewUser.member">
            <xacml3:Description>Members can view their own user record only
            </xacml3:Description>
            <xacml3:Target />
            <xacml3:Condition>
                <xacml3:Apply
                    FunctionId="urn:oasis:names:tc:xacml:3.0:function:any-of-any">
                    <xacml3:Function
                        FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal" />
                    <xacml3:AttributeDesignator
                        AttributeId="axiomatics.user.username"
                        Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
                        DataType="http://www.w3.org/2001/XMLSchema#string"
                        MustBePresent="false" />
                    <xacml3:AttributeDesignator
                        AttributeId="axiomatics.record.owner"
                        Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
                        DataType="http://www.w3.org/2001/XMLSchema#string"
                        MustBePresent="false" />
                </xacml3:Apply>
            </xacml3:Condition>
        </xacml3:Rule>
    </xacml3:Policy>
    <xacml3:Policy
        PolicyId="http://axiomatics.com/alfa/identifier/haris.users.updateUser"
        RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable"
        Version="1.0">
        <xacml3:Description>Update user</xacml3:Description>
        <xacml3:PolicyDefaults>
            <xacml3:XPathVersion>http://www.w3.org/TR/1999/REC-xpath-19991116
            </xacml3:XPathVersion>
        </xacml3:PolicyDefaults>
        <xacml3:Target>
            <xacml3:AnyOf>
                <xacml3:AllOf>
                    <xacml3:Match
                        MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
                        <xacml3:AttributeValue
                            DataType="http://www.w3.org/2001/XMLSchema#string">update</xacml3:AttributeValue>
                        <xacml3:AttributeDesignator
                            AttributeId="axiomatics.actionId"
                            Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action"
                            DataType="http://www.w3.org/2001/XMLSchema#string"
                            MustBePresent="false" />
                    </xacml3:Match>
                </xacml3:AllOf>
            </xacml3:AnyOf>
        </xacml3:Target>
        <xacml3:Rule Effect="Permit"
            RuleId="haris.users.updateUser.administrator">
            <xacml3:Description>Administrator can update any user
            </xacml3:Description>
            <xacml3:Target>
                <xacml3:AnyOf>
                    <xacml3:AllOf>
                        <xacml3:Match
                            MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
                            <xacml3:AttributeValue
                                DataType="http://www.w3.org/2001/XMLSchema#string">administrator</xacml3:AttributeValue>
                            <xacml3:AttributeDesignator
                                AttributeId="axiomatics.user.role"
                                Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
                                DataType="http://www.w3.org/2001/XMLSchema#string"
                                MustBePresent="false" />
                        </xacml3:Match>
                    </xacml3:AllOf>
                </xacml3:AnyOf>
            </xacml3:Target>
        </xacml3:Rule>
        <xacml3:Rule Effect="Permit"
            RuleId="haris.users.updateUser.owner">
            <xacml3:Description>Owner can update any user</xacml3:Description>
            <xacml3:Target>
                <xacml3:AnyOf>
                    <xacml3:AllOf>
                        <xacml3:Match
                            MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
                            <xacml3:AttributeValue
                                DataType="http://www.w3.org/2001/XMLSchema#string">owner</xacml3:AttributeValue>
                            <xacml3:AttributeDesignator
                                AttributeId="axiomatics.user.role"
                                Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
                                DataType="http://www.w3.org/2001/XMLSchema#string"
                                MustBePresent="false" />
                        </xacml3:Match>
                    </xacml3:AllOf>
                </xacml3:AnyOf>
            </xacml3:Target>
        </xacml3:Rule>
    </xacml3:Policy>
    <xacml3:Policy
        PolicyId="http://axiomatics.com/alfa/identifier/haris.users.deleteUser"
        RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable"
        Version="1.0">
        <xacml3:Description>Delete user</xacml3:Description>
        <xacml3:PolicyDefaults>
            <xacml3:XPathVersion>http://www.w3.org/TR/1999/REC-xpath-19991116
            </xacml3:XPathVersion>
        </xacml3:PolicyDefaults>
        <xacml3:Target>
            <xacml3:AnyOf>
                <xacml3:AllOf>
                    <xacml3:Match
                        MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
                        <xacml3:AttributeValue
                            DataType="http://www.w3.org/2001/XMLSchema#string">delete</xacml3:AttributeValue>
                        <xacml3:AttributeDesignator
                            AttributeId="axiomatics.actionId"
                            Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action"
                            DataType="http://www.w3.org/2001/XMLSchema#string"
                            MustBePresent="false" />
                    </xacml3:Match>
                </xacml3:AllOf>
            </xacml3:AnyOf>
        </xacml3:Target>
        <xacml3:Rule Effect="Permit"
            RuleId="haris.users.deleteUser.administrator">
            <xacml3:Description>Administrator can delete any user
            </xacml3:Description>
            <xacml3:Target>
                <xacml3:AnyOf>
                    <xacml3:AllOf>
                        <xacml3:Match
                            MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
                            <xacml3:AttributeValue
                                DataType="http://www.w3.org/2001/XMLSchema#string">administrator</xacml3:AttributeValue>
                            <xacml3:AttributeDesignator
                                AttributeId="axiomatics.user.role"
                                Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
                                DataType="http://www.w3.org/2001/XMLSchema#string"
                                MustBePresent="false" />
                        </xacml3:Match>
                    </xacml3:AllOf>
                </xacml3:AnyOf>
            </xacml3:Target>
        </xacml3:Rule>
    </xacml3:Policy>
</xacml3:PolicySet>

执行策略

对于不同的角色/用户,我如何为单个API返回不同的数据?

假设您有一个API,例如 /api/profiles/{profileID}。您可以使用以下两种方式来使用API:

  • GET /api/profiles 将返回用户有权查看的所有配置文件
  • GET /api/profiles/123 如果用户有权查看,则返回配置文件123,否则返回HTTP 403(或404 - 您可以认为您甚至不想透露该配置文件确实存在)。

要做到这一点,您需要实现一个策略实施点(PEP)。这可以是WSO2的API Manager。PEP负责:

  1. 解析传入的API调用(GET /api/profile/123)
  2. 将其转换为授权请求,例如:Alice是否可以查看配置文件123?
  3. 将请求发送给PDP
  4. 处理从PDP收到的响应 - 特别是提取决策(例如允许)。
如果决策是允许,则呼叫将转发到您的后端API。如果不是,则可以按照之前讨论的返回HTTP 403/404。
如果是403,则呼叫确实会传递到后端,最终从您的后端返回响应并通过PEP进行处理,在那里它可以再次调用PDP,例如以删除数据为例。
“我是否需要在服务器中涉及业务逻辑,例如获取导航栏项目、获取API使用情况统计信息、管理员的完全数据访问权限以及所有者和成员的组织/部门受限数据?如何执行这些基本操作?”
不需要。在构建菜单或导航项时,您还可以调用PDP并询问给定用户是否可以访问给定的功能集,例如“Alice是否可以查看导航栏项目#123?”您需要最少的业务逻辑来调用PDP。

1
感谢@David提供详细的答案。我有些困惑,如何为单个API但针对不同角色/用户返回不同的数据。我需要在我的服务器中涉及业务逻辑,例如获取“导航栏”项目、获取API使用统计信息、管理员完全访问数据以及所有者的组织/部门和成员受限数据。如何执行这些基本操作? - Haris Qurashi
谢谢 David。让我试着实现上述用例。最后一个问题:PDP和PEP通过WSO2的一些教程能分享一下吗? - Haris Qurashi
你需要向WSO2团队咨询,抱歉。 - David Brossard
1
非常好的回答,即使我没有使用相同的技术栈,也对我有很大帮助! - bombillazo

2

经过一些观察,我可以想到一件事情。

使用上述的 WSO2 APIM API 来获取给定 APIswagger.json(这些应该/将会有所有可用的API)。现在使用相关的 HTTP-verbs 来映射资源和角色以及响应。

例如,如果成员不能访问 DELETE,那么我们可以使用这种方法向服务器请求返回当前页面/视图的所有权限,并在前端将这些值映射为隐藏/显示按钮/视图或整个内容。

缺点: 为了避免重复和重复,我们可以将这些映射保存在我们的数据库中。但这个逻辑需要一些业务逻辑在你自己的服务器上以及对数据库读/写操作的访问。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接