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-securitykeycloak-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

没有 JSP 的 Spring Security /j_spring_security_check

Spring-Security