我正在构建我的多租户 Symfony 应用程序的下一个版本。
可以说我的租户是公司。每个公司都有我的应用程序域的子域。
例如,company1.example.com、company2.example.com。
Apache 配置了 ServerAlias *.example.com
我编写了一个 UserProvider,以便用户在公司和电子邮件地址中是唯一的。相同的电子邮件地址可以在 company1 和 company2 注册,但就 Symfony 而言,它们是不同的用户。我有一项服务,它查看主机名以确定公司。FilterControllerEvent 处理程序使 Company 对象神奇地在控制器中可用。
这一切都很好。
但是……那些公司有部门。例如,公司 1 - 部门 1,
公司 1 - 部门 2,
公司 2 - 部门 3
对于大多数操作,divideId 将是第一个参数,所以 ...
company1.example.com/1
company1.example.com/2
现在的并发症。一个用户可能在不同的部门有不同的角色。company1 的用户 1 可能在部门 1 有 ROLE_BOSS,但在部门 2 有 ROLE_WORKER。
UserProvider 从数据库加载角色。这目前基于电子邮件地址和公司,但是......它也可以基于 URL 参数吗?我想我需要将 Request 对象注入我的 UserProvider 并查看属性。这种方法有什么问题吗?这有点太笨拙了吗?
我一直在燃烧大脑周期,试图找出最好的方法来做到这一点。我的要求基本上是:
公司用户的单一登录(基于电子邮件地址),即使他们访问多个部门并且在这些部门中具有不同的角色。
公司不相关,因此允许不同公司使用相同的电子邮件地址。如果用户确实在多家公司拥有帐户,那么他可以分别登录每个公司并使用书签或其他方式在它们之间进行访问。对于用户来说,它们是独立的、不相关的站点。
用户应该能够在部门之间进行切换,而无需再次登录。
Symfony 防火墙系统应该“正常工作”。User1 应该能够访问 company1.example.com/1/BossStuff 但不能访问 company1.example.com/2/BossStuff 仅基于我的 UserProvider 加载的角色,而不是每个控制器操作中繁琐的安全检查代码(在那里做过) .
我考虑过的其他方法是...
每个部门都有一个唯一的子域。部门 id 表示公司 id,因此用户仍然可以是公司唯一的。我们不再需要 divisionId URL 参数。那么问题是用户在同一公司的部门之间移动时需要登录。
上述部门的唯一子域,但将 PHP 会话 cookie 设为 .example.com 而不是子域。这解决了在部门之间再次登录的需要,但如果你想在公司之间切换会变得混乱。您无法同时登录 company1 和 company2。
同样,部门的唯一子域,子域中的 cookie,但有一些其他身份验证机制,因此当登录到 company1-division1.example.com 时,它会在 .example.com 上放置一个唯一的 cookie,因此如果您随后访问 company1-division2.example .com,它会读取该 cookie 并自动将您登录。可能有效,但从安全角度来看会有点混乱和可怕。我不确定我是否想去那里。
我已经阅读了有关身份验证提供程序、访问控制列表、选民等的信息。我认为它们在这里对我没有多大帮助。
感谢您的任何想法。