实际上,您不应该尝试实施新的授权模型。已经有一个很好的模型,称为基于属性的访问控制(或 ABAC - 请参阅 SO 标记abac和xacml)。
ABAC 是一种授权模型,它:
- 由美国国家标准与技术研究院 NIST 定义,该组织定义了 RBAC(基于角色的访问控制)
- 使用属性来定义访问控制逻辑。属性
- 是一个键值对,例如角色 == 经理
- 可以是多值的,例如公民身份 = 加拿大、瑞典
- 可以描述任何内容,例如请求用户、目标对象、动作、关系、时间、位置……
- 使用策略来定义访问控制逻辑。这些政策
- 用 XACML ( xacml )编写
- 使用属性定义访问控制范围
- 启用外部授权:本质上,您的授权逻辑与您的业务逻辑分离。这很棒,因为您可以独立于安全性开发应用程序。
让我们举个例子:
Tim 可以看到 Mary 的个人资料信息,因为 Tim 是 Mary 的朋友。
因此,授权要求是:
A user can view another user's profile if both users are friends.
在 ABAC 中,您必须识别您的属性。你在你的问题中这样做很好,尽管你的分析是偏向于角色的。让我们再来一次。我看到的属性是:
- 操作 ID(视图)
- 资源类型(用户配置文件)
- 朋友列表(蒂姆的朋友列表)
- 个人资料所有者(玛丽)
有了这些属性,我可以用分解的方式重写你的需求:
A user can do the action actionId==view on a resource of type==user profile if profile.owner is in the user's friend list.
然后,您可以使用 ALFA ( alfa ) 在ALFA和 XACML 中实施策略。
namespace com.axiomatics{
/**
* A user can view another user's profile...
*/
policy viewProfile{
target clause actionId=="view" and resourceType=="user profile"
apply firstApplicable
/**
* Allow if both users are friends.
*/
rule allowIfFriends{
condition stringIsIn(stringOneAndOnly(subjectId), friendList)
permit
}
}
}
XACML 结果(在 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:Policy xmlns:xacml3="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17"
PolicyId="http://axiomatics.com/alfa/identifier/com.axiomatics.viewProfile"
RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable"
Version="1.0">
<xacml3:Description>A user can view another user's profile...</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="urn:oasis:names:tc:xacml:1.0:action:action-id"
DataType="http://www.w3.org/2001/XMLSchema#string"
Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action"
MustBePresent="false"
/>
</xacml3:Match>
<xacml3:Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<xacml3:AttributeValue
DataType="http://www.w3.org/2001/XMLSchema#string">user profile</xacml3:AttributeValue>
<xacml3:AttributeDesignator
AttributeId="resourceType"
DataType="http://www.w3.org/2001/XMLSchema#string"
Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
MustBePresent="false"
/>
</xacml3:Match>
</xacml3:AllOf>
</xacml3:AnyOf>
</xacml3:Target>
<xacml3:Rule
Effect="Permit"
RuleId="http://axiomatics.com/alfa/identifier/com.axiomatics.viewProfile.allowIfFriends">
<xacml3:Description>Allow if both users are friends.</xacml3:Description>
<xacml3:Target />
<xacml3:Condition>
<xacml3:Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-is-in" >
<xacml3:Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only" >
<xacml3:AttributeDesignator
AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id"
DataType="http://www.w3.org/2001/XMLSchema#string"
Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
MustBePresent="false"
/>
</xacml3:Apply>
<xacml3:AttributeDesignator
AttributeId="friendList"
DataType="http://www.w3.org/2001/XMLSchema#string"
Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
MustBePresent="false"
/>
</xacml3:Apply>
</xacml3:Condition>
</xacml3:Rule>
</xacml3:Policy>