我正在为基于B2B SaaS的应用程序构建一个安全模块(身份验证和授权)。我们有一个简单的身份验证机制,即用户名和密码与MFA。然而,授权部分有点复杂。规则如下:
我们有两个域对象,我们称之为D1和D2。D2是D1的子节点,具有从D1到D2的一对多Map。D1和D2都链接有其他域对象或模块,但是对它们的访问可以基于对D1或D2的访问来计算。现在,对于授权部分,我们需要3个级别的角色。级别1角色不知道可以在平台上执行任何操作的任何域对象(如global_admin)。2级角色需要知道D1标识符,并且它们只能对直接链接到这些D1对象的资源进行操作,3级角色的情况也是如此,其中底层域对象将是D3。
还有一个术语叫做权限组。因此,每当我们将所有这3个角色分配给用户时,我们都会将其保存到权限组,因此用户不会直接Map到角色,而是通过称为权限组的中间层,以便我们可以为其他用户重用以前的权限组,如果需要任何更改,我们将对权限组进行更改,效果将适用于所有链接的用户。
服务器使用Sping Boot 编写,安全性通过Spring Security处理。我正在探索使用Auth0等身份提供程序实现此功能的可能性。
什么是可能的方式来实现这一点?
1条答案
按热度按时间k4aesqcs1#
对于第一级角色,这只是传统的RBAC:角色与用户的关联以及基于该角色的访问控制。Auth0支持角色,Spring安全性也是如此(他们称之为
GrantedAuthority
)。您所要做的就是提供一个Converter<Jwt, ? extends Collection<? extends GrantedAuthority>>
并在Converter<Jwt, JwtAuthenticationToken>
中使用它。就像这样:字符串
对于第二和第三级别,我看到两个选项,这取决于用户和D1或D2之间的基数:
Authentication
(而不是JwtAuthenticationToken
,使用AbstractAuthenticationToken
作为基类),其中包含隐藏私有声明访问细节的方法,并使SpEL语法更轻。Authentication
示例和D1或D2标识符作为参数,并返回一个布尔值进行访问。由于您可以在SpEL中引用bean,因此调用这样的服务非常简单。在任何情况下,SpEL中的
authentication
“魔术”变量以及对@PathVariable
的引用在编写@PreAuthorize
表达式时都会有很大的帮助。在JWT中使用私有声明的解决方案有一个很大的优势:每次令牌发布仅发生一次数据库访问以获得用户与D1、D2之间的关联,这将使其更好地扩展。
型
第一种方法需要提供一个
Authentication
和canReadD1
方法(使用私有声明),第二种方法需要提供一个authorizationService
bean和canReadD1
方法(使用数据库)。