2012-03-07 133 views
3

我有一个Rails应用程序作为一个OAuth 2.0提供者(使用oauth2-provider宝石)。它存储所有与用户有关的信息(账户,个人信息和角色)。有2个客户端应用程序都通过这个应用程序进行身份验证。客户端应用程序可以使用client_credentials授权类型通过电子邮件查找用户,并执行其他不需要授权代码的事情。用户还可以使用密码授权类型登录到客户端应用程序。OAuth2用户和基于角色的访问控制

现在我们面临的问题是用户的角色是在资源主机上全局定义的。因此,如果在资源主机上为用户分配admin角色,则该用户在两个客户端上都是admin。我的问题是:我们应该做些什么来实现更细粒度的访问控制?即用户可以是editorapp1,但不是app2

我想最简单的方式来做到这一点是改变像这样的角色名:app1-adminapp2-adminapp1-editorapp2-editor等更大的问题是:我们是否正确执行这一整个系统;也就是说,我们应该在资源主机上存储如此多的信息,还是应该将数据非规范化到客户端应用程序上?

非规范化架构如下所示:资源主机上的所有用户数据,每个客户端主机上的本地化用户数据。因此[email protected]将在资源主机上拥有他的个人信息,并将其editor角色存储在客户端app1上。如果他从不使用它,app2可能完全不知道他的存在。

非规范化模型的缺点是会有大量数据(帐户ID,角色)和代码(每个客户端上的UserRole模型,单独的管理界面等)的重复数据。

保持数据分离有什么缺点吗?客户端应用程序都非常值得信赖 - 我们都是这样做的 - 但我们很可能会添加额外的客户端应用程序,这些应用程序将来不在我们的控制范围之内。

回答

3

到使用OAuth和其它类似的外部授权方法,因为我看到的最正确的方法,是严格的身份验证。所有业务/授权逻辑应始终在服务器部分进行处理,并且应始终保留用户的中心记录,并按外部类型的身份验证服务链接到外部信息。

具有多/多组访问的,也是必须的,如果你希望你的设置是可扩展的,面向未来的。这是一种与任何授权逻辑分开的标准设计,并且始终与业务规则直接相关。

Stackoverflow做了这样的事情,要求您在之后使用外部方法登录后在网站上创建实际帐户。

更新:如果这些网站非常相似,您可以将此设计的子集分配给每个应用程序的对象,以保持应用程序特定的访问规则。该对象还必须从具有全局规则的全局对象继承(因此您可以例如在应用程序范围或企业范围内实施禁止)。

我会去包含接取设置/可涉及到两个应用程序级别设置和全局设置的情况下,仅用于自动压缩访问的分配对象和角色。

其实你可以使用这个设计,即使它们不是太相似。这将帮助您避免重复设置和无意义(商业)角色。您可以纯粹通过职位/目的来确定角色,然后通过链接到适当的访问设置设置来强制您的限制。

+0

我可以看到这方面的智慧,但想想在多个应用程序中重新实现常见行为是一个不争的事实。例如,每个站点都需要一个管理界面来搜索用户帐户,分配用户角色等。由于我们的所有站点都属于同一个组织(类似于Stackoverflow),因此拥有一个集中的用户管理界面似乎很有意义。我想我们可以编写一个gem来为多个网站添加相同的功能。 – 2012-03-07 15:55:37

+0

@Reed更新一下然后 – 2012-03-07 16:08:33

+0

您可以使用OpenId Connect并在用于实现您的RBAC的JWT使用中将用户角色作为声明返回 – 2017-04-24 15:48:10