如何使用选民检查用户权限
编辑本页警告:您正在浏览的文档欧宝官网下载appob娱乐下载Symfony 4.1,现已不再维护。
读本页的更新版本用于Syob娱乐下载mfony 6.2(当前稳定版本)。
如何使用选民检查用户权限
安全投票人是检查权限的最细粒度的方式(例如。“这个特定的用户可以编辑给定的项目吗?”)。这篇文章详细地解释了选民。
提示
看一下授权文章对选民有更深入的了解。
Symfob娱乐下载ony如何利用选民
为了利用选民,您必须了解Symfony如何与他们合作。ob娱乐下载的时候,所有的投票人都会被调用isGranted ()
方法的授权检查器或调ob娱乐下载用denyAccessUnlessGranted ()
在一个控制器中(使用授权检查器)。
最终,Symfony从所ob娱乐下载有投票者那里获得反馈,并根据应用程序中定义的策略做出最终决定(允许或拒绝访问资源),可以是:肯定、一致或一致。
更多信息请看关于访问决策管理器的部分.
选民界面
需要实现的自定义投票人VoterInterface或扩展选民,这使得创建投票者更加容易:
1 2 3 4 5 6 7 8
使用ob娱乐下载\组件\安全\核心\身份验证\令牌\TokenInterface;使用ob娱乐下载\组件\安全\核心\授权\选民\VoterInterface;摘要类选民实现了VoterInterface{摘要受保护的函数支持($属性,$主题);摘要受保护的函数voteOnAttribute($属性,$主题, TokenInterface$令牌);}
设置:检查控制器中的访问
假设你有一个帖子
对象,您需要决定当前用户是否可以编辑或视图对象。在你的控制器中,你会用这样的代码检查访问:
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
/ / src /控制器/ PostController.php/ /……类为PostController扩展AbstractController{/ * * *@Route("/posts/{id}", name="post_show") */公共函数显示($id){//获取Post对象——例如查询它$帖子=……;// check for "view" access:调用所有投票人$这->denyAccessUnlessGranted (“视图”,$帖子);/ /……}/ * * *@Route("/posts/{id}/edit", name="post_edit") */公共函数编辑($id){//获取Post对象——例如查询它$帖子=……;//检查“edit”权限:调用所有投票人$这->denyAccessUnlessGranted (“编辑”,$帖子);/ /……}}
的denyAccessUnlessGranted ()
方法(以及isGranted ()
方法)调用“voter”系统。现在,没有选民会投票决定用户是否可以“查看”或“编辑”一个帖子
.但是你可以创建你的自己的投票人用任何你想用的逻辑来决定。
创建自定义投票人
假设决定用户是否可以“查看”或“编辑”a的逻辑帖子
对象非常复杂。例如,用户
可以随时编辑或查看帖子
他们创造了。如果帖子
被标记为“公共”,任何人都可以查看。这种情况下的投票者应该是这样的:
12 34 56 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
/ / src /安全/ PostVoter.php名称空间应用程序\安全;使用应用程序\实体\帖子;使用应用程序\实体\用户;使用ob娱乐下载\组件\安全\核心\身份验证\令牌\TokenInterface;使用ob娱乐下载\组件\安全\核心\授权\选民\选民;类PostVoter扩展选民{//这些字符串只是被发明出来的:你可以使用任何东西常量视图=“视图”;常量编辑=“编辑”;受保护的函数支持($属性,$主题){//如果该属性不是我们支持的,返回false如果(!in_array ($属性, (自我::看来,自我::编辑])){返回假;}//只对该投票人内部的Post对象投票如果(!$主题运算符Post) {返回假;}返回真正的;}受保护的函数voteOnAttribute($属性,$主题, TokenInterface$令牌){$用户=$令牌->getUser ();如果(!$用户运算符用户){//用户必须登录;如果不是,则拒绝访问返回假;}//你知道$subject是Post对象,感谢支持/**@varPost $ Post */$帖子=$主题;开关($属性) {情况下自我::观点:返回$这->canView ($帖子,$用户);情况下自我::编辑:返回$这->canEdit ($帖子,$用户);}扔新\ LogicException (“不能到达这个密码!”);}私人函数canView(文章$帖子、用户$用户){//如果他们可以编辑,他们可以查看如果($这->canEdit ($帖子,$用户)) {返回真正的;}// Post对象可以有一个方法isPrivate()//检查布尔值$private属性返回!$帖子->isPrivate ();}私人函数canEdit(文章$帖子、用户$用户){//假设数据对象有一个getOwner()方法//获取拥有该数据对象的用户的实体返回$用户= = =$帖子->getOwner ();}}
就是这样!投票人完成了!接下来,配置它.
概括一下,下面是对这两个抽象方法的期望:
-
选民::支持(属性、主题)美元
-
当
isGranted ()
(或denyAccessUnlessGranted ()
)调用时,第一个参数在这里传递为美元的属性
(如。ROLE_USER
,编辑
),第二个参数(如果有的话)传递为美元的主题
(如。零
,一个帖子
对象)。您的工作是确定您的投票者是否应该对属性/主题组合进行投票。如果返回true,voteOnAttribute ()
将被调用。否则,你的投票人已经完成了:其他投票人应该处理这个。在本例中,返回真正的
如果属性为视图
或编辑
如果物体是a帖子
实例。 -
voteOnAttribute($attribute, $subject, TokenInterface $token)
-
如果你回来
真正的
从支持()
,则调用此方法。你的工作很简单:回来真正的
允许访问和假
拒绝访问。的美元的令牌
可用于查找当前用户对象(如果有的话)。在本例中,包含了所有复杂的业务逻辑以确定访问权限。
配置投票者
要将投票人注入安全层,必须将其声明为服务并标记为security.voter
.但是如果你用默认的服务。yaml的配置,这将自动为您完成!当你用view/edit调用isgranting()并传递一个Post对象,您的投票人将被执行,您可以控制访问。
检查Voter中的角色
如果你想打电话怎么办isGranted ()
从内部您的选民-例如,您想要查看当前用户是否有ROLE_SUPER_ADMIN
.这可以通过注入安全变成你的选民。你可以用这个来,例如,总是允许访问具有的用户ROLE_SUPER_ADMIN
:
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
/ / src /安全/ PostVoter.php/ /……使用ob娱乐下载\组件\安全\核心\安全;类PostVoter扩展选民{/ /……私人$安全;公共函数__construct(安全$安全){$这->安全=$安全;}受保护的函数voteOnAttribute($属性,$主题, TokenInterface$令牌){/ /……// ROLE_SUPER_ADMIN可以做任何事情!的力量!如果($这->安全->isGranted (“ROLE_SUPER_ADMIN”)) {返回真正的;}/ /……这都是正常的选民逻辑}}
如果你在用默认的服务。yaml的配置,你完蛋了!ob娱乐下载Symfony将自动通过security.helper
服务,当实例化你的选民(感谢autotowiring)。
更改访问决策策略
通常情况下,在任何给定的时间内,只有一名选民会投票(其余的选民将“弃权”,这意味着他们将返回投票假
从支持()
).但在理论上,您可以让多个投票者投票支持一个动作和对象。例如,假设有一个投票人检查用户是否是站点的成员,另一个投票人检查用户是否超过18岁。
为了处理这些情况,访问决策管理器使用访问决策策略。您可以配置它以满足您的需要。有三种策略可供选择:
-
肯定的
(默认) - 一旦有机会,就会立即授予访问权限一个允许进入的投票人;
-
共识
- 如果允许访问的选民多于拒绝访问的选民,则允许访问;
-
一致
-
只有当没有选民拒绝访问时,才允许访问。如果所有选民都投了弃权票,则该决定以投票结果为依据
allow_if_all_abstain
配置选项(默认为假
).
在上面的场景中,两个投票人都应该授予访问权,以便授予用户阅读文章的访问权。在这种情况下,默认策略不再有效一致
应该改为使用。你可以在安全配置中设置:
- YAML
- XML
- PHP
1 2 3 4 5
#配置/包/ security.yaml安全:access_decision_manager:策略:一致allow_if_all_abstain:假