亚马逊AWS官方博客
使用 Amazon Verified Permissions 服务帮您简化管理应用程序授权流程 — 现已正式发布
在开发新应用程序或将现有应用程序集成到新环境中时,需要花费大量精力才能正确实施用户身份验证和授权。过去,可以构建自己的身份验证系统来完成这一操作,但现在可以使用如 Amazon Cognito 这样的外部身份提供程序。不过,授权逻辑通常要在代码中实现。
这开始的时候可能十分简便,为所有用户分配了其工作职能的角色。但是,随着时间的推移,这些权限变得越来越复杂。随着权限变得更加精细,角色的数量也随之增加。新的使用案例推动了对自定义权限的需求。例如,某个用户可能与另一个担任其他角色的用户共享文档,或者支持代理可能需要临时访问客户账户才能解决问题。管理代码中的权限容易出错,在审计权限和决定具体访问人和访问内容时,尤其当这些权限在不同的应用程序中以多种编程语言呈现时,将是一大难题。
在 re:Invent 2022 上,我们推出了 Amazon Verified Permissions 预览版,该服务为您的应用程序提供细粒度的权限管理和授权服务,可以在任何规模下使用。Amazon Verified Permissions 将权限集中到策略存储库中,帮助开发人员使用这些权限来授权用户在其应用程序中的操作。与身份提供程序简化身份验证的方式类似,策略存储库允许您以一致且可扩展的方式管理授权。
为了更好地定义细粒度权限,Amazon Verified Permissions 使用了 Cedar 套件,这是一种用于进行访问控制的开源策略语言和软件开发工具包(SDK)。您可以根据主体类型、资源类型和有效操作为您的授权模型定义架构。这样,创建策略时,将根据您的授权模型对其进行验证。可以使用模板简化类似策略的创建过程。对策略存储库的更改进行审计,以便可以查看到更改人和更改时间。
然后,可以通过 AWS 开发工具包将应用程序连接到 Amazon Verified Permissions,以授权访问请求。对于每个授权请求,均会检索和评估相关策略,以确定该操作是否被允许。您可以重现这些授权请求以确认权限是否按预期运行。
今天,我很高兴地宣布正式推出 Amazon Verified Permissions 服务,AWS 管理控制台增加了更多的新功能,为用户带来更加精简方便的操作体验。
让我们看看这项服务的具体使用方法。
使用 Amazon Verified Permissions 创建策略存储库
在 Amazon Verified Permissions 控制台中,选择创建策略存储库。策略存储库是存储策略和架构的逻辑容器。授权决策根据策略存储库中的所有策略做出。
可以使用不同的方法配置新的策略存储库。可以从引导式设置、示例策略存储库(例如照片共享应用程序、在线商店或任务管理器)或空策略存储库(建议高级用户使用)开始。选择引导式设置,为我的架构输入命名空间(MyApp
),然后选择下一步。
资源是主体可以对之采取行动的对象。在我的应用程序中,具有可以创建、读取、更新和删除文档
(资源)的用户
(主体)。开始定义文档
资源类型。
输入资源类型的名称并添加两个必填属性:
所有者
(字符串),用于指定文档的所有者。isPublic
(布尔值)用于标记任何人都可以阅读的公共文档。
为文档
资源类型指定了四个操作:
DocumentCreate
DocumentRead
DocumentUpdate
DocumentDelete
输入用户
作为将在文档
上使用这些操作的主体类型的名称。然后,选择下一步。
现在,配置用户
主体类型。可以使用自定义配置来集成外部身份源,但在这种情况下,使用的是我之前创建的 Amazon Cognito 用户群体。选择连接用户群体。
在对话框中,选择用户群体所在的 AWS 区域,输入用户群体 ID,然后选择连接。
Amazon Cognito 用户群体已连接后,可以通过验证客户端应用程序 ID 来增加另一级别的保护。现在,选择不使用这个选项。
在主体属性部分,选择策略中计划用于基于属性的访问控制的具体属性。选择 sub
(主题),用于根据 OpenID Connect 规范识别最终用户。可以选择更多属性。例如,可以在策略中使用 email_verified
来仅向电子邮件已通过验证的 Amazon Cognito 用户授予权限。
作为策略存储库创建工作的一部分,我创建了第一个策略用于为用户 danilop
提供权限读取 doc.txt
文档。
在以下代码中,通过控制台可预览使用 Cedar 语言生成的策略。
最后,选择创建策略存储库。
向策略存储库添加权限
现在策略存储库已创建,在导航窗格中选择策略。在创建策略下拉列表中,选择创建静态策略。静态策略包含评估所需的所有信息。在我的第二个策略中,允许任何用户阅读公共文档。默认情况下,所有操作都是禁止的,因此在策略效应中,选择允许。
在策略范围中,选中所有主体和所有资源,然后选择 DocumentRead
操作。在策略部分,更改 when
条件子句,以限制对特定资源(isPublic
等于 true
)的权限:
为策略输入描述内容并选择创建策略。
对于第三个策略,创建另一个静态策略,以允许文档所有者拥有完全访问权限。同样,在策略效应中,选择“允许”,在策略范围中,选择所有主体和所有资源。此时,选中所有操作。
在策略部分,更改 when
条件子句,以限制对特定资源(所有者
等于主体的 sub
)的权限:
在我的应用程序中,我需要针对非文档所有者的特定用户允许读取权限。为了简化这一流程,创建了一个策略模板。借助这一策略模板,我从使用占位符作为其某些值(例如主体或资源)的模板来创建策略。模板中的占位符是以 ?
字符开头的关键字。
在导航窗格中,选择策略模板,然后选择创建策略模板。接着,输入描述内容并使用以下策略模板正文。使用此模板时,可以为占位符 ?principal
和 ?resource
指定值。
我完成了策略模板的创建。现在,使用这个模板来简化策略创建过程。在导航窗格中选择策略,然后在创建策略下拉列表中选择创建模板链接的策略。选择刚创建的策略模板并选择下一步。
如果要向用户(danilop
)提供特定文档(new-doc.txt
)的访问权限,只需发送以下值(请注意,MyApp
是策略存储库的命名空间):
- 对于主体:
MyApp::User::"danilop"
- 对于资源:
MyApp::Document::"new-doc.txt"
我完成了策略创建。接下来测试这些策略是否按预期运行。
在控制台中测试策略
在我的应用程序中,可以使用 AWS SDK 来运行授权请求。控制台提供了一种方法来模拟应用程序将要执行的操作。在导航窗格中选择测试台。为了简化测试,使用视觉模式。作为替代方案,可以选择使用与 SDK 中相同的 JSON 语法。
作为主体,我发送了 janedoe
用户。作为资源,我使用了 requirements.txt
。该文档不是公共文档(isPublic
为 false
),并且所有者
属性等于 janedoe
的 sub
。在操作中,选择 MyApp::Action::"DocumentUpdate"
。
运行授权请求时,我可以向其他实体发送有关与请求相关的主体和资源的更多信息。现在,先把这部分留空。
选择顶部的运行授权请求来查看基于当前策略做出的决定。正如预期,该决定是允许的。在这里,还可以查看到授权请求满足的具体策略。在这种情况下,策略允许文档所有者拥有完全访问权限。
可以测试其他值。如果将文档的所有者和操作更改为 DocumentRead
,则决策被拒绝。如果随后将资源属性 isPublic
设置为 true
,则决定是允许的,因为有一项策略允许所有用户阅读公共文档。
处理权限中的群组
我的应用程序中的管理用户要有权限删除任何文档。为此,我为管理员用户创建了一个角色。首先,在导航窗格中选择架构,然后选择编辑架构。在实体类型列表中,选择添加一个新的实体类型。接着,使用角色
作为类型名称,并添加。然后,在实体类型中选择用户
,并编辑它,将角色
添加为父级。保存更改并创建了以下策略:
在测试台中,运行授权请求来检查用户 jeffbarr
能否删除 (DocumentDelete
) 资源 doc.txt
。由于他不是资源的所有者,因此请求被拒绝。
现在,在其他实体中,添加以 jeffbarr
作为标识符的 MyApp::User
实体。作为父级,添加以管理员
作为标识符的 MyApp::Role
实体,然后确认。控制台发出警告消息指出,实体 MyApp::Role::"admin"
已被引用,但其他实体数据中并未包含。选择添加该实体,解决这个问题。
再次运行授权请求时,请求被允许,原因是在其他实体中,主体(jeffbarr
)是管理员
。
在您的应用程序中使用 Amazon Verified Permissions
在我的应用程序中,可以使用 isAuthorized
API 操作(如果主体来自外部身份来源,则使用 isAuthrizedWithToken
)运行授权请求。
例如,以下 Python 代码使用适用于 Python 的 Amazon SDK(Boto3) 来检查用户是否有权限读取文档。授权请求使用我刚创建的策略存储库。
import boto3
import time
verifiedpermissions_client = boto3.client("verifiedpermissions")
POLICY_STORE_ID = "XAFTHeCQVKkZhsQxmAYXo8"
def is_authorized_to_read(user, resource):
authorization_result = verifiedpermissions_client.is_authorized(
policyStoreId=POLICY_STORE_ID,
principal={"entityType": "MyApp::User", "entityId": user},
action={"actionType": "MyApp::Action", "actionId": "DocumentRead"},
resource={"entityType": "MyApp::Document", "entityId": resource}
)
print('Can {} read {} ?'.format(user, resource))
decision = authorization_result["decision"]
if decision == "ALLOW":
print("Request allowed")
return True
else:
print("Request denied")
return False
if is_authorized_to_read('janedoe', 'doc.txt'):
print("Here's the doc...")
if is_authorized_to_read('danilop', 'doc.txt'):
print("Here's the doc...")
我运行这段代码后,正如预期,输出内容与之前运行的测试一致。
可用性和定价
Amazon Verified Permissions 现已在所有商用 AWS 区域提供,但不包括位于中国的区域。
使用 Amazon Verified Permissions 时,您只需根据授权请求的数量和向服务发出的 API 调用数量为实际用量支付费用。有关更多信息,请参阅 Amazon Verified Permissions 定价。
通过 Amazon Verified Permissions,您可以使用 Cedar 策略语言配置细粒度权限,并简化应用程序的代码。通过这种方式,权限可以保留在集中存储区中,并且更易于审计。在此处,您可以阅读关于我们如何通过自动推理和差分测试构建 Cedar 的详细信息。
使用 Amazon Verified Permissions 管理应用程序的授权。
— Danilo