我有一个Rails应用程序充当OAuth 2.0提供程序(使用
oauth2-provider gem).它存储与用户(帐户,个人信息和角色)相关的所有信息.有2个客户端应用程序都通过此应用程序进行身份验证.客户端应用程序可以使用client_credentials授权类型通过电子邮件查找用户,并执行其他不需要授权代码的操作.用户还可以使用密码授予类型登录客户端应用程序.
现在我们面临的问题是用户角色是在资源主机上全局定义的.因此,如果在资源主机上为用户授予管理员角色,则该用户在两个客户端上都是管理员.我的问题是:我们应该做些什么才能获得更细粒度的访问控制?即用户可以是app1的编辑器,但不能是app2的编辑器.
我想这样做的简单方法就是更改角色名称:app1-admin,app2-admin,app1-editor,app2-editor等.更大的问题是:我们是否正确实现了整个系统;也就是说,我们应该在资源主机上存储这么多信息,还是应该将数据反规范化到客户端应用程序上?
非规范化体系结构如下所示:资源主机上的所有用户数据,每个客户端主机上的本地化用户数据.因此user@example.com将在资源主机上拥有他的个人信息,并将其编辑器角色存储在客户端app1上.如果他从不使用它,app2可能完全忘记了他的存在.
非规范化模型的缺点是会有大量的数据重复(帐户ID,角色)和代码(每个客户端上的用户和角色模型,单独的管理界面等).
保持数据分离有什么缺点吗?客户端应用程序都是高度可信的 – 我们同时制作它们 – 但我们可能会在未来添加不受我们控制的其他客户端应用程序.
最佳答案 在我看来,使用oAuth和其他类似外部授权方法的最恰当方法是严格的身份验证.所有业务/授权逻辑应始终在您的服务器部分处理,并且您应始终保留用户的中央记录,链接到每个外部类型的auth服务的外部信息.
如果您希望您的设置具有可扩展性和面向未来,那么拥有多级/多部分访问权限也是必须的.这是一种标准设计,与任何授权逻辑分开,并始终与业务规则直接相关.
Stackoverflow会执行类似这样的操作,要求您在使用外部方法登录后在站点上创建实际帐户.
更新:如果站点非常相似,您可以将此设计子集化为每个应用程序的对象,该对象保留应用程序特定的访问规则.此对象还必须从具有全局规则的全局对象继承(因此您可以在应用程序范围内或企业范围内强制禁止).
我会选择包含访问设置的对象,以及可以与应用程序级别设置和全局设置的实例相关的角色,仅用于自动化/压缩访问分配.
实际上即使它们不太相似也可以使用这种设计.这将帮助您避免冗余设置和无意义(业务方面)角色.您可以完全按作业标题/目的标识角色,然后通过链接到适当的访问设置设置来强制实施限制.