有一个使用JWT保护端点的Spring启动应用。令牌验证由Spring启动OAuth2资源服务器执行,该服务器在Keycloak授权服务器上检查令牌。如何在成功通过Keycloak授权后将额外的内部用户验证添加到应用程序?
所以我想建立某种链-如果令牌通过认证服务器的验证,然后我检查从本地数据库的JWT获取的用户名。
在资源服务器上检查访问令牌对本地数据库的访问控制在身份验证转换器(http.oauth2ResourceServer().jwt().jwtAuthenticationConverter(...)
或http.oauth2ResourceServer().opaqueToken().authenticationConverter(...)
)中是一项简单的任务,但这是非常低效的:在授权服务器上创建令牌时对数据库进行一次访问要好得多,而不是在资源服务器授权过程中(对每个请求都发生)每次都进行评估。
访问控制决策所需的所有数据应该已经包含在令牌中。如果需要的不仅仅是来自授权服务器的标准声明和默认私有声明,那么可以配置该授权服务器,以便在发出访问令牌时添加所需的关于用户的数据。对于Keycloak,这是通过所谓的"OIDC协议映射"完成的。它们可以发出数据库请求、web服务调用和其他任何事情。在这个项目中,我有一个映射器的示例,它添加了一个带有web服务调用值的私有声明。
一旦您需要的所有数据都在令牌中,您只需在资源服务器的Spring安全表达式中正常使用它。下面是我的教程中的一个工作示例:
@PreAuthorize("is(#username) or isNice() or onBehalfOf(#username).can('greet')")
在这个表达式中,检查用户是否:
- 向自己问好(
username
@PathVariable
等于访问令牌中的preferred_username
claim) - 有一个"nice"角色
- 代表
preferred_username
等于username
@PathVariable
的用户拥有greet
的权限(路由是/greet/{username}
,此权限委托来自于由上面链接的示例中的映射器添加的私有声明)