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

使用Keycloak Spring Boot库管理API权限

Spring Boot REST API 集成最新Keycloak授权方案

一、依赖选择(替代过时的Keycloak Spring Security Adapter)

官方已弃用旧的keycloak-spring-security-adapter,推荐直接使用Spring Security原生的OAuth2资源服务器支持,配合Keycloak的OpenID Connect实现授权。以下是Maven和Gradle的依赖配置:

Maven(pom.xml)

<dependencies>
    <!-- Spring Security 核心依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <!-- OAuth2 资源服务器支持 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
    </dependency>
    <!-- 若需Keycloak管理API操作,可添加此依赖 -->
    <dependency>
        <groupId>org.keycloak</groupId>
        <artifactId>keycloak-admin-client</artifactId>
        <version>22.0.5</version> <!-- 使用最新稳定版 -->
    </dependency>
</dependencies>

Gradle(build.gradle)

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-security'
    implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server'
    // 可选:Keycloak管理客户端
    implementation 'org.keycloak:keycloak-admin-client:22.0.5'
}

二、核心配置

1. 应用配置文件(application.yml)

配置Keycloak的OpenID Connect元数据地址、JWT验证相关参数:

spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          # Keycloak Realm的OpenID配置地址,替换为你的实际地址
          issuer-uri: http://localhost:8080/realms/your-realm-name
          # 可选:指定受众(需与Keycloak客户端的"Valid Audiences"匹配)
          audience: your-client-id

2. Spring Security 配置类

编写配置类实现资源服务器的授权规则,同时处理Keycloak JWT中的角色转换(Keycloak角色默认存储在realm_access.roles字段中):

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            // REST API无需会话,禁用会话创建
            .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
            // 关闭CSRF(REST API无需)
            .csrf(csrf -> csrf.disable())
            // 配置授权规则
            .authorizeHttpRequests(auth -> auth
                // 公开接口(如健康检查)无需授权
                .requestMatchers("/actuator/**", "/public/**").permitAll()
                // 需要admin角色的接口
                .requestMatchers("/api/admin/**").hasAuthority("ROLE_admin")
                // 需要user角色的接口
                .requestMatchers("/api/user/**").hasAuthority("ROLE_user")
                // 其余所有接口需认证
                .anyRequest().authenticated()
            )
            // 启用OAuth2资源服务器JWT验证
            .oauth2ResourceServer(oauth2 -> oauth2.jwt(jwt -> jwt.jwtAuthenticationConverter(jwtAuthenticationConverter())));

        return http.build();
    }

    // 自定义JWT转换器,将Keycloak的realm角色转换为Spring Security权限
    @Bean
    public JwtAuthenticationConverter jwtAuthenticationConverter() {
        JwtGrantedAuthoritiesConverter grantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
        // 设置角色前缀,Spring Security默认前缀为SCOPE_,这里替换为ROLE_
        grantedAuthoritiesConverter.setAuthorityPrefix("ROLE_");
        // 指定从JWT的哪个字段获取角色,Keycloak默认是realm_access.roles
        grantedAuthoritiesConverter.setAuthoritiesClaimName("realm_access.roles");

        JwtAuthenticationConverter jwtAuthenticationConverter = new JwtAuthenticationConverter();
        jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(grantedAuthoritiesConverter);
        return jwtAuthenticationConverter;
    }
}

三、API授权示例

编写受保护的REST接口,验证授权效果:

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api")
public class ProtectedController {

    @GetMapping("/user/profile")
    public String userProfile() {
        return "仅用户角色可访问此接口";
    }

    @GetMapping("/admin/dashboard")
    public String adminDashboard() {
        return "仅管理员角色可访问此接口";
    }
}

四、关键注意事项

  • Keycloak客户端配置:确保你的Keycloak客户端设置为Access Type = confidential(服务端应用),并在Valid Audiences中配置与application.yml中audience一致的客户端ID。
  • 角色配置:在Keycloak Realm中创建对应的admin、user角色,并分配给用户。
  • JWT验证:确保issuer-uri指向正确的Keycloak Realm地址,Spring会自动获取公钥验证JWT签名,无需手动配置密钥。

内容的提问来源于stack exchange,提问作者Slim Mintya

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 09:55:28