You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot 3+Keycloak:如何按用户组设置并限制资源服务器作用域?

问题描述

我正在开发基于Spring Boot 3和Spring Security 6的REST API应用,采用Spring Security资源服务器做授权,端点通过注解@PreAuthorize("hasAuthority('SCOPE_scope-name')")限制访问,使用OIDC、JWT协议,以Keycloak作为授权服务器。

需求:

  • 按用户组限制资源访问:用户a、b、c需拥有read:test和write:test作用域,用户x、y仅拥有read:test作用域,即使x、y请求write:test,Keycloak也不应发放该作用域。
  • 希望通过用户组管理用户,创建对应角色并分配给组,每个角色关联允许的作用域。但查阅文档后因作用域与角色的多位置配置感到困惑,不知如何实现。

另外疑问:根据Spring Security文档,仅需在application.properties中配置spring.security.oauth2.resourceserver.jwt.issuer-uri,但不理解Spring应用仅通过该配置如何识别Keycloak中对应的客户端/资源服务器。

核心问题:在Keycloak中,如何设置、管理资源服务器的API端点作用域,并按用户进行限制?

解决方案

一、Keycloak端完整配置步骤

1. 定义资源服务器的作用域

  • 登录Keycloak控制台,进入目标Realm
  • 左侧菜单选择「Clients」,找到API对应的客户端(即资源服务器端的客户端),进入「Client scopes」标签页
  • 点击「Create client scope」,分别创建read:test和write:test两个作用域:
    • 类型选「Optional」(后续通过角色控制是否发放),完成保存后,这两个作用域会归属当前客户端的可用作用域列表

2. 创建关联作用域的角色

  • 左侧菜单选择「Roles」,点击「Create role」:
    • 创建test-full-access角色,描述为「拥有test资源的读写权限」
    • 创建test-read-only角色,描述为「仅拥有test资源的只读权限」
  • 进入每个角色的「Client scopes」标签页,为角色绑定对应作用域:
    • 给test-full-access添加read:test和write:test作用域
    • 给test-read-only只添加read:test作用域

3. 用用户组批量管理权限

  • 左侧菜单选择「Groups」,点击「New group」:
    • 创建test-full-users组,进入组的「Role mappings」标签页,添加test-full-access角色
    • 创建test-read-only-users组,进入组的「Role mappings」标签页,添加test-read-only角色
  • 将用户a、b、c加入test-full-users组,用户x、y加入test-read-only-users组

4. 配置作用域发放的权限规则

  • 回到API客户端的「Settings」标签页,找到「Authorization」部分,开启「Authorization Enabled」
  • 进入「Authorization」标签页,依次配置策略与权限:
    • 策略配置:选择「Policies」→「Create policy」→「Role policy」:
      • 策略1:名称allow-test-full,关联test-full-access角色,逻辑设为「Positive」
      • 策略2:名称allow-test-read,关联test-read-only角色,逻辑设为「Positive」
    • 权限配置:选择「Permissions」→「Create permission」→「Scope permission」:
      • 权限1:名称grant-read-test,关联read:test作用域,绑定allow-test-full和allow-test-read策略
      • 权限2:名称grant-write-test,关联write:test作用域,仅绑定allow-test-full策略
        完成后,只有test-full-users组的用户能获取write:test作用域,只读组用户请求该作用域会被Keycloak直接拒绝。

二、关于Spring Boot中issuer-uri的疑问解答

Spring Security通过issuer-uri配置,会自动请求Keycloak的/.well-known/openid-configuration端点获取元数据,其中包含JWT公钥、授权端点等核心信息。这里的逻辑是:

  • Spring Boot作为资源服务器,核心是验证JWT的合法性(签名、签发方、过期时间等),以及JWT中的scope声明是否匹配端点的@PreAuthorize规则,不需要提前指定客户端ID
  • 如果需要限制仅特定客户端能访问API,才需要额外配置spring.security.oauth2.resourceserver.jwt.audiences,指定Keycloak中对应的客户端ID,Spring会校验JWT的aud(受众)声明是否匹配

三、Spring Boot端补充配置

确保application.properties中包含基础配置,按需添加客户端限制:

spring.security.oauth2.resourceserver.jwt.issuer-uri=http://your-keycloak-domain/realms/your-realm
# 如需限制特定客户端访问,添加以下配置
# spring.security.oauth2.resourceserver.jwt.audiences=your-api-client-id

端点权限控制保持使用@PreAuthorize("hasAuthority('SCOPE_read:test')")和@PreAuthorize("hasAuthority('SCOPE_write:test')")即可,Spring Security会自动解析JWT中的scope字段,添加SCOPE_前缀作为权限标识。

内容的提问来源于stack exchange,提问作者Mirza Prangon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 15:57:11