Spring Security + Keycloak 授权:如何将端点与资源相关联?
Posted
技术标签:
【中文标题】Spring Security + Keycloak 授权:如何将端点与资源相关联?【英文标题】:Spring Security + Keycloak Authorization: How to associate an endpoint with a Resource? 【发布时间】:2021-01-26 22:29:37 【问题描述】:我创建了一个带有 spring-boot-starter-security
和 keycloak-spring-security-adapter
的 Spring Boot 应用程序,并且使用 Keycloak 对用户进行身份验证按预期工作。
我现在想使用 Keycloak 的 Authorization Services 对我的 API 进行细粒度的访问控制。
在 Keycloak 中,我为我的客户启用了授权。我创建了一个角色并将该角色分配给我的测试用户。我创建了一个资源和一个基于资源的权限,并添加了一个基于角色的策略。使用评估功能,我已确认我的用户有权访问我的资源。
假设我有以下带有一个端点的控制器。
@RestController
class GreetingController
@GetMapping("/hello")
fun getPatientInfo(principal: Principal): String
return "Hello, $principal.name!"
现在我的问题是:如何将 Spring Boot 应用程序中的端点与给定资源相关联,以便在发出请求时评估权限?
【问题讨论】:
如果您不介意,请给您几个问题? (1) 到目前为止,您尝试过什么? (2) 如果到目前为止您的尝试导致错误,那么错误消息究竟是什么? (3) 你用的是什么版本的Spring Boot、Keycloak、JDK等? (4) 您的应用部署在什么操作系统上? (5)您使用什么构建工具(如果有)构建您的应用程序? (6)您认为任何其他细节可能有助于帮助您重现您观察到的任何故障? (7) 请分享MRE 好吗? TIA 【参考方案1】:„...如何将 Spring Boot 应用程序中的端点与给定资源相关联,以便在发出请求时评估权限?...“
举个例子,比如说……
您的 Keycloak 服务器正在端口 8585 上运行 您的应用服务器正在端口 8080 上运行 您的领域名为„myrealm
“
您的资源名为“my-client-resource
”
您的角色名为“super-user
”
然后在你的 Spring Boot 应用程序的 application.properties 文件中设置……
#port on which the application would run
server.port = 8080
keycloak.realm = myrealm
keycloak.auth-server-url = http://localhost:8585/auth
keycloak.ssl-required = none
#keycloak resource is the client ID
keycloak.resource = my-client-resource
keycloak.use-resource-role-mappings = true
keycloak.public-client = true
…
# Configures what $principal.name will return
keycloak.principal-attribute=preferred_username
然后你通过……钩入 Spring Boot 的 Keycloak 配置
…
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity( prePostEnabled = true )
@ComponentScan( basePackageClasses = KeycloakSecurityComponents.class )
public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter
@Override
public void configure( HttpSecurity http ) throws Exception
super.configure( http );
http.authorizeRequests( )
.antMatchers( "/hello", "…" )
.hasRole( "super-user" )
.anyRequest( )
.permitAll( );
…
在没有您的应用程序和配置的更具体细节的情况下,以上是一个草图。但这是一般方法。
为了更具体地掌握上述一般方法,download and play with this MRE 我最近实现了for another answer。
【讨论】:
感谢您的回答,并对不具体的问题表示抱歉。有没有办法拥有多个端点并将每个端点关联到不同的资源? „...有多个端点并且每个端点都关联到不同的资源?...“– @KirillRakhman – 是的。每个资源都可以有自己的 rootUrl、redirecUris 等。作为另一个可能的一般示例,搜索“如果您有多个部署”在文档的“Securing WARs via Adapter Subsystem”部分。但让我强调一点:我并不是在提议将该页面上的内容作为您特定要求的解决方案。我只是指出这是 Keycloak 可以做的一般事情。 也许我有一个XY Problem,我应该更广泛地提出我的问题。如何将不同的权限应用于不同的端点以实现基于角色的访问控制?我不在乎它是否通过资源完成,但hasRole('admin')
是不够的,因为它检查的是角色,而不是权限。
„也许我有一个 XY 问题“ - 老实说,我不能说。但我确实同意 What to do about it? 部分:„(1) ...包括关于……任何尝试的解决方案的信息…… (2) 如果有人要求提供更多信息,请提供详细信息……“ — „ ...但是hasRole('admin')
是不够的,因为它检查的是角色,而不是权限...“ - 感谢您排除了这一点。我将使用 Resource-based Permissions 并相应地编辑我的答案。同时,请参阅我昨天在 cmets 提交的 7 请求以获取更多信息? TIA。
@KirillRakhman,通过 Keycloak 适配器的策略执行者为您完成所有这些工作。您不需要在 Spring Security 构建器中声明 RBAC。所以;执行您在 Keycloak 策略和资源中的所有定义。如果您删除 @deduper 答案仍然是正确的 .andMatchers(...).hasRole(...)
以上是关于Spring Security + Keycloak 授权:如何将端点与资源相关联?的主要内容,如果未能解决你的问题,请参考以下文章
Spring boot REST API 仅接受来自 Angular 前端的调用
Spring 中的 spring-security-oauth2 与 spring-security-oauth2-core
Spring mvc / security:从spring security中排除登录页面
Spring Security:2.4 Getting Spring Security