Symfony3 授权流程

3
我正在学习Symfony 3,并需要一些指引来实现动态授权和身份验证过程。首先,认证部分大部分已经完成,我按照Symfony文档中的链接完成了这一步骤:http://symfony.com/doc/current/security/entity_provider.html。我还需要理解如何实现接口函数getRoles() 以便从数据库返回一个值(我有一个与用户表相关的角色表)。其次,是授权部分。我的应用程序要求最终用户创建自己的访问机制,换句话说,我有一个界面,用户可以创建角色,然后定义该角色将能够访问哪些页面以及拥有哪些权限(例如创建、读取、更新、删除等)。之后角色被分配给应用程序用户。总之,这是相当标准的东西,因此Symfony必须有一种干净的方式来实现它。 我目前所想到的是使用ACL,所以我按文档中的操作做:http://symfony.com/doc/current/security/acl.html。 我真诚的问题是:现在怎么办?我应该采取哪些步骤来完全实现身份验证机制?为了保持并检索访问规则,我现在应该做什么?我如何将它们与用户角色联系起来? P.S.:这个问题可能有点重复,请原谅,但说实话,那些问题对我没有帮助,文档中的搜索也是如此。
1个回答

3

所以,你的问题非常广泛。不管怎样,这是一个好问题,我会尽力回答。

认证

这里没有什么可说的,我只希望你按照文章中建议的使用FOSUserBundle:它是在Symfony中实现注册/登录系统的最佳方式,并且它将让你了解整个过程的工作原理。如果你不是一位Symfony经验丰富的开发者,从零开始似乎不是最好的选择。

试试FOSUserBundle吧!

授权过程

关于授权,你基本上有两个选择:使用Voters和使用ACL

根据我的经验,使用Voters是最佳选择。

事实上,在大多数情况下,实体之间存在双向引用(请参见Doctrine关于此的文档),用户和拥有权限的对象之间存在这种情况时,不需要使用ACL,甚至是不建议使用。
实际上,ACL仅仅是在两个对象(在您的用例中是用户和文章)之间创建一个关系。为了管理此关系,它使用数据库中的表,因此必须查询该表以获取关系并检查授权权限。
但是,如果您的实体之间已经存在用户和文章/组之间的双向引用,则已经建立了此关系,因此您可以使用投票者,使用ACL是多余的,甚至如上所述是不建议的,因为这是无用的重复。
如果您的实体中没有这种双向关系,请创建它:将来肯定会有用,无论如何,您都将能够直接从实体树中访问链接的实体!
在您的场景中,由于您在对象上拥有自定义权限/特权,因此无法使用ACL:投票者再次是构建这种事情的最佳选择。 不要使用ACL,而是使用投票者 如何继续 我会做的第一件事是在接口中列出所有可用的特权:毕竟,它们与您的应用程序业务逻辑密切相关,因为用户无法使某人能够执行您的应用程序不能执行的操作:如果您的应用程序没有实现编辑流程,则用户无法让某人编辑文章。这很明显。
因此,像这样的东西可能很好:
interface PrivilegesEnum
{
   const CREATE = 1;
   const EDIT   = 2;
   const DELETE = 4;
   const READ   = 8;
   const OTHER  = 16;
   // ... Other privileges
}

正如您所看到的,我为每个权限赋予了一个数字值:这将使您能够使用位掩码,这是一种非常强大的机制来管理此类事物:它允许您仅使用数据库中的一个字段列出所有权限。

您可以在此处了解有关位掩码的更多信息:

我曾经使用过这个系统,以下是我收集的一些有用链接,它们可能会对你有所帮助!
构建一个列出权限的表单
另一个你可能会觉得有用的事情是一个FormType,可以列出你可用的权限:你可以写一个简单的自定义FormType来实现这个功能。
如何管理角色
要管理角色,请阅读Security组件如何管理角色以及FOSUserBundle在Stackoverflow上)。
用户、组和文章之间的关系
一旦你到达了这个点,你应该有更多的实体,了解Doctrine关系机制的更多信息,你就能够将用户与他们的角色、组和文章相关联。
无论如何,您都将拥有所需的概念和实用工具,以便在具体实现中进行更好的思考。
最后说明:
正如您所看到的,实现这种类型的授权过程并不简单。
我建议您仔细考虑是否真的需要在应用程序开发的这个阶段使用它,因为如果您可以将其推迟到未来,那么我建议您这样做。
如果您想尽快上线,实施此系统将需要大量时间来学习、实现、调试和重构代码(我说的是几周,而不是几天!)。
因此,如果您有这么多时间,那么就去实现这个系统。但如果您觉得自己没有这么多时间,那么就使用更“静态”的系统,上线,然后使其更加“动态”。
毕竟,这是精益创业时代
祝你好运!

2
为这个答案慢慢鼓掌!对于任何对授权/认证主题感兴趣的人来说,这是一座金矿... - Jovan Perovic
非常感谢您的回复,我会尽快操作并反馈给您我的意见。我知道正确实现这个可能需要一些时间,但我真的需要它。我已经使用Java从头开始完成了此任务,但我没有使用框架,因为它们会限制你按照它们的方式去做事情。所以我对其背后的逻辑有很好的掌握(事实上我再次尝试进行操作,并试图“覆盖”Symfony安全配置,但我知道这是不可行的)。基本上,我仅仅是在努力理解Symfony的处理方式。 - Eduardo
选民们...... 老实说,只是说“使用选民”并没有真正解决我的问题,也许我只是没有理解关于它们的文档。而且我想我意识到了为什么,所以让我问你一个问题:我需要为每个对象创建一个选民吗? - Eduardo
2
对于广泛的问题,唯一的答案是广泛的回答。很抱歉,但事实就是如此...我没有只简单地告诉你“使用投票者”,而是向你解释了为什么你应该使用它们而不是ACL。而且,正如框架所做的那样,Stackoverflow也有其自己的规则:提出具体的代码问题,并附上代码示例,以解决具体、单一、真实的问题。我回答了一个非常广泛的问题,涉及许多不同的主题,并指引你走上了正确的道路。 - Aerendir
1
现在,你又问了我一个问题:我无法回答。我不能简单地回答,因为这是另一个话题,而且我没有答案:你应该先尝试,然后失败,再提问。在这个过程中,你会找出你想要编写软件的方式。你可以只编写一个投票者,也可以编写10个或100个。我不知道。我对你的软件一无所知,对你编写的代码、编写代码的方式也一无所知。很抱歉。不管怎样,也许这会帮助你:http://stackoverflow.com/questions/28179013/using-one-class-voter-for-many-entities尝试一下,然后再问。 - Aerendir

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接