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

编辑该页面

警告:你浏览的文档欧宝体育电话欧宝娱乐app下载地址Symfony 3.0,不再维护。

这个页面的更新版本Symf欧宝娱乐app下载地址ony 6.2(当前的稳定版本)。

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

在Sy欧宝娱乐app下载地址mfony中,您可以检查使用权限访问数据ACL模块许多应用程序,这有点势不可挡。一个更简单的解决方案是使用定制选民,类似于简单的条件语句。

提示

看一看授权章在选民们更深入的理解。

Symf欧宝娱乐app下载地址ony如何使用选民

为了使用选民,你必须理解Symfony是如何工作的。欧宝娱乐app下载地址所有选民被称为每次使用isGranted ()在Symfony的授欧宝娱乐app下载地址权检查器(即方法security.authorization_checker服务)。每一个决定如果当前用户可以访问一些资源。

最终,Symfony将所欧宝娱乐app下载地址有选民的反应,使最终决定允许或拒绝访问资源()根据应用程序中定义的策略,可以:肯定的,或一致的共识。

看一看的更多信息部分的访问决策管理器

选民的接口

一个定制的选民需要实现VoterInterface或扩展选民,这使得创建一个选民更容易。

1 2 3 4 5
文摘选民实现了VoterInterface{文摘受保护的函数支持(美元属性,美元主题);文摘受保护的函数voteOnAttribute(美元属性,美元主题,TokenInterface美元令牌);}

设置:检查访问控制器

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

1 2 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 / AppBundle /控制器/ PostController.php/ /……为PostController扩展控制器{/ * * *@Route(“/文章/ {id}”, name = " post_show ") * /公共函数showAction(美元id){/ /获取Post对象,如查询美元帖子=……;/ /检查“视图”访问:所有选民的电话美元- >denyAccessUnlessGranted (“视图”,美元帖子);/ /……}/ * * *@Route(“/文章/ {id} /编辑”,name = " post_edit ") * /公共函数editAction(美元id){/ /获取Post对象,如查询美元帖子=……;/ /检查“编辑”访问:所有选民的电话美元- >denyAccessUnlessGranted (“编辑”,美元帖子);/ /……}}

denyAccessUnlessGranted ()(而且,简单的方法isGranted ()方法)所说的“选民”系统。现在,没有选民将投票决定是否用户可以“视图”或“编辑”帖子。但是你可以创造你自己的选民决定使用任何你想要的逻辑。

提示

denyAccessUnlessGranted ()函数和isGranted ()函数都是快捷方式调用isGranted ()security.authorization_checker服务。

创建定制的选民

假设的逻辑来决定如果用户可以“视图”或“编辑”帖子对象是非常复杂的。例如,一个用户可以编辑或查看吗帖子他们创造了。如果一个帖子被标记为“公开”,任何人都可以查看。选民对这种情况是这样的:

1 2 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 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 / AppBundle /安全/ PostVoter.php名称空间AppBundle\安全;使用AppBundle\实体\帖子;使用AppBundle\实体\用户;使用欧宝娱乐app下载地址\组件\安全\核心\身份验证\令牌\TokenInterface;使用欧宝娱乐app下载地址\组件\安全\核心\授权\选民\选民;PostVoter扩展选民{/ /这些字符串只是发明:您可以使用任何东西常量视图=“视图”;常量编辑=“编辑”;受保护的函数支持(美元属性,美元主题){/ /如果属性不是一个我们支持,返回false如果(! in_array (美元属性,数组(自我::看来,自我::编辑))){返回;}/ /只在Post对象在选民投票如果(!美元主题运算符Post) {返回;}返回真正的;}受保护的函数voteOnAttribute(美元属性,美元主题,TokenInterface美元令牌){美元用户=美元令牌- >getUser ();如果(!美元用户运算符用户){/ /用户必须登录;如果不是,拒绝访问返回;}/ /你知道美元的主题是Post对象,感谢支持/ * *@var后美元* /美元帖子=美元主题;开关(美元属性){情况下自我::观点:返回美元- >canView (美元帖子,美元用户);情况下自我::编辑:返回美元- >canEdit (美元帖子,美元用户);}\ LogicException (“这段代码不应达到!”);}私人函数canView(文章美元帖子、用户美元用户){/ /如果他们可以编辑,他们可以查看如果(美元- >canEdit (美元帖子,美元用户)){返回真正的;}/ / Post对象可以,例如,一个方法isPrivate ()/ /检查一个布尔美元的私人财产返回!美元帖子- >isPrivate ();}私人函数canEdit(文章美元帖子、用户美元用户){/ /这个假设数据对象getOwner()方法/ /获取用户拥有该数据对象的实体返回美元用户= = =美元帖子- >getOwner ();}}

就是这样!选民做!接下来,配置它

回顾一下,这是预期的两个抽象方法:

选民::支持(属性、主题)美元
isGranted ()(或denyAccessUnlessGranted ()),第一个参数是通过这里美元的属性(如。ROLE_USER,编辑),第二个参数(如果有的话)被传递美元的主题(如。,一个帖子对象)。你的工作是确定你的选民应该投票属性/主题的组合。如果你返回true,voteOnAttribute ()将被调用。否则,你的选民做:其他选民应该处理这个问题。在本例中,您回来了真正的如果attribue视图编辑如果对象是一个帖子实例。
voteOnAttribute(属性,主题,美元TokenInterface美元令牌)
如果你返回真正的支持(),然后调用此方法。你的工作很简单:回报真正的允许访问和拒绝访问。的美元的令牌可以用来找到当前用户对象(如果有的话)。在这个例子中,所有的复杂的业务逻辑包含确定访问。

配置选民

安全层注入选民,你必须声明它作为服务和标记security.voter:

  • YAML
  • XML
  • PHP
1 2 3 4 5 6 7 8
# app / config / services.yml服务:app.post_voter:类:AppBundle \安全\ PostVoter标签:- - - - - -{名称:security.voter}#小性能提升公众:

你已经完成了!现在,当你调用isGranted()查看/编辑和发布对象,你的选民将会被执行,并且可以控制访问。

检查角色在选民

如果你想叫什么isGranted ()内部你的选民——如你想看看当前用户ROLE_SUPER_ADMIN。可能的注入AccessDecisionManager到你的选民。例如,您可以使用它来总是允许访问用户ROLE_SUPER_ADMIN:

1 2 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 / AppBundle /安全/ PostVoter.php/ /……使用欧宝娱乐app下载地址\组件\安全\核心\授权\AccessDecisionManagerInterface;PostVoter扩展选民{/ /……私人美元decisionManager;公共函数__construct(AccessDecisionManagerInterface美元decisionManager){美元- >decisionManager =美元decisionManager;}受保护的函数voteOnAttribute(美元属性,美元主题,TokenInterface美元令牌){/ /……/ / ROLE_SUPER_ADMIN可以做任何事!的力量!如果(美元- >decisionManager- >决定(美元令牌,数组(“ROLE_SUPER_ADMIN”))){返回真正的;}/ /……所有正常的选民逻辑}}

接下来,更新services.yml注入的security.access.decision_manager服务:

  • YAML
  • XML
  • PHP
1 2 3 4 5 6 7 8
# app / config / services.yml服务:app.post_voter:类:AppBundle \安全\ PostVoter参数:(“@security.access.decision_manager”)公众:标签:- - - - - -{名称:security.voter}

就是这样!调用决定()AccessDecisionManager本质上是一样的isGranted ()从一个控制器或其他地方
(它只是一个小低层,选民是必要的)。

请注意

security.access.decision_manager是私人的。这意味着你不能访问它直接从控制器:你只能注入到其他服务。没关系:使用security.authorization_checker而不是在所有情况下,除了选民。

改变访问决策策略

通常情况下,只有一个选民将投票在任何给定的时间(其余的将“弃权”,这意味着他们的回报支持())。但在理论上,你可以让多个选民投票给一个行动和对象。例如,假设您有一个选民,检查如果用户是网站的一员,第二个检查用户年龄超过18岁。

处理这些情况下,访问决策管理器使用一个访问决策策略。你可以配置来满足您的需求。有三种策略:

肯定的(默认)
这就授予访问权限一个选民授予访问;
共识
授予访问权限如果有更多的选民比拒绝授予访问;
一致
这只授予访问权限所有选民授权访问。

在上面的场景中,选民应该授权访问以授权访问用户读过了那篇文章。在这种情况下,默认的战略不再有效一致应该使用。你可以设置在安全配置:

  • YAML
  • XML
  • PHP
1 2 3 4
# app / config / security.yml安全:access_decision_manager:策略:一致
这项工作,包括代码示例,许可下Creative Commons冲锋队3.0许可证。