如何使用选民检查用户权限

编辑本页

如何使用选民检查用户权限

选民是Symfony管ob娱乐下载理权限的最强大的方式。它们允许您集中所有权限逻辑,然后在许多地方重用它们。

然而,如果你不重用权限或者你的规则是基本的,你总是可以把逻辑直接放到你的控制器中。下面是一个例子,如果你想让一个路由只对“所有者”可访问:

1 2 3 4 5 6 7
/ / src /控制器/ PostController.php/ /……//在你的控制器动作如果帖子->getOwner () = =->getUser ()) {->createAccessDeniedException ();}

从这个意义上讲,本页所使用的下面的例子对于选民来说是一个最小的例子。

下面是Symfony与ob娱乐下载投票人的工作方式:每次使用isGranted ()方法的授权检查器或调ob娱乐下载用denyAccessUnlessGranted ()在控制器中(使用授权检查器),或通过访问控制

最终,Symfony从所ob娱乐下载有投票人那里得到反馈,并根据这些反馈做出最终决定(允许或拒绝访问资源)应用程序中定义的策略,可以是肯定的、一致的、一致的或优先的。

选民界面

需要实现的自定义投票人VoterInterface或扩展选民,这使得创建投票者更加容易:

1 2 3 4 5 6 7 8
使用ob娱乐下载组件安全核心身份验证令牌TokenInterface使用ob娱乐下载组件安全核心授权选民VoterInterface摘要选民实现了VoterInterface摘要受保护的函数支持(字符串属性、混合主题保龄球摘要受保护的函数voteOnAttribute(字符串属性、混合主题, TokenInterface令牌保龄球;}

提示

对于执行大量权限检查的应用程序来说,多次检查每个投票人可能会很耗时。在这些情况下,要提高性能,可以让投票人实现CacheableVoterInterface.这允许访问决策管理器记住投票人支持的主题的属性和类型,以便每次只调用所需的投票人。

设置:检查控制器中的访问

假设你有一个帖子对象,您需要决定当前用户是否可以编辑视图对象。在你的控制器中,你会用这样的代码检查访问:

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
/ / src /控制器/ PostController.php/ /……为PostController扩展AbstractController#[路由('/posts/{id}',名称:'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
/ / src /安全/ PostVoter.php名称空间应用程序安全使用应用程序实体帖子使用应用程序实体用户使用ob娱乐下载组件安全核心身份验证令牌TokenInterface使用ob娱乐下载组件安全核心授权选民选民PostVoter扩展选民//这些字符串只是被发明出来的:你可以使用任何东西常量视图=“视图”常量编辑=“编辑”受保护的函数支持(字符串属性、混合主题保龄球//如果该属性不是我们支持的,返回false如果(!in_array (属性, (自我::看来,自我::编辑])){返回;}//只对Post对象投票如果(!主题运算符Post) {返回;}返回真正的;}受保护的函数voteOnAttribute(字符串属性、混合主题, TokenInterface令牌保龄球用户令牌->getUser ();如果(!用户运算符用户){//用户必须登录;如果不是,则拒绝访问返回;}//你知道$subject是Post对象,这要感谢' supports() '/**@varPost $ Post */帖子主题返回匹配(属性){自我::视图= >->canView (帖子用户),自我::编辑= >->canEdit (帖子用户),默认的= >\ LogicException (“不能到达这个密码!”)};}私人函数canView(文章帖子、用户用户保龄球//如果他们可以编辑,他们可以查看如果->canEdit (帖子用户)) {返回真正的;}// Post对象可以有一个方法' isPrivate() '返回帖子->isPrivate ();}私人函数canEdit(文章帖子、用户用户保龄球//假设Post对象有一个' 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_equal_granted_denied配置选项(默认为真正的);
一致
只有当没有选民拒绝访问时,才允许访问。
优先级
这允许或拒绝第一个没有弃权的选民访问,基于他们的服务优先级;

无论选择哪种策略,如果所有选民都投了弃权票,则该决定是基于allow_if_all_abstain配置选项(默认为).

在上面的场景中,两个投票人都应该授予访问权,以便授予用户阅读文章的访问权。在这种情况下,默认策略不再有效一致应该改为使用。你可以在安全配置中设置:

  • YAML
  • XML
  • PHP
1 2 3 4 5
#配置/包/ security.yaml安全:access_decision_manager:策略:一致allow_if_all_abstain:

自定义访问决策策略

如果没有任何内置策略适合您的用例,则定义strategy_service选项来使用自定义服务(您的服务必须实现AccessDecisionStrategyInterface):

  • YAML
  • XML
  • PHP
1 2 3 4 5
#配置/包/ security.yaml安全:access_decision_manager:strategy_service:App \安全\ MyCustomAccessDecisionStrategy#……

自定义访问决策管理器

如果需要提供完全自定义的访问决策管理器,请定义服务选项来使用自定义服务作为访问决策管理器(您的服务必须实现AccessDecisionManagerInterface):

  • YAML
  • XML
  • PHP
1 2 3 4 5
#配置/包/ security.yaml安全:access_decision_manager:服务:App \安全\ MyCustomAccessDecisionManager#……
此工作,包括代码示例,是根据创作共用BY-SA 3.0许可证。
ob娱乐下载Symfony 6.0支持通过SensioLabs