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

如何在Spring Security中让OidcUser同步KeyCloak用户资料变更?

解决KeyCloak用户资料更新后OidcUser数据不同步的问题

核心思路

默认的OidcUserService仅在首次认证时拉取用户信息,后续不会主动同步KeyCloak中的资料变更。要实现数据自动更新,需自定义OidcUserService,在每次认证(含令牌刷新流程)中主动调用OIDC的/userinfo端点,获取最新用户属性并更新OidcUser对象。

具体实现步骤

1. 自定义OidcUserService类

继承DefaultOidcUserService并重写loadUser方法,在原有逻辑基础上新增调用/userinfo端点的逻辑,用最新数据覆盖原有OidcUser属性:

import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserRequest;
import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserService;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.oidc.OidcIdToken;
import org.springframework.security.oauth2.core.oidc.OidcUserInfo;
import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser;
import org.springframework.security.oauth2.core.oidc.user.OidcUser;

public class CustomOidcUserService extends OidcUserService {

    @Override
    public OidcUser loadUser(OidcUserRequest userRequest) throws OAuth2AuthenticationException {
        // 先通过默认逻辑获取基础OidcUser
        OidcUser originalUser = super.loadUser(userRequest);
        
        // 调用/userinfo端点拉取最新用户信息
        OidcUserInfo latestUserInfo = this.retrieveUserInfo(userRequest);
        
        // 用最新信息重新构建OidcUser,覆盖原有属性
        OidcIdToken idToken = originalUser.getIdToken();
        return new DefaultOidcUser(
                originalUser.getAuthorities(),
                idToken,
                latestUserInfo,
                "name" // 指定映射姓名的字段,对应KeyCloak中的name属性
        );
    }
}

2. 配置Spring Security替换默认服务

在Spring Security配置类中,将自定义的OidcUserService注入到OAuth2登录流程:

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.oauth2.client.oidc.userinfo.OidcUserService;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .authorizeHttpRequests(auth -> auth.anyRequest().authenticated())
                .oauth2Login(oauth2 -> oauth2
                        .userInfoEndpoint(userInfo -> userInfo
                                .oidcUserService(customOidcUserService())
                        )
                );
        return http.build();
    }

    @Bean
    public OidcUserService customOidcUserService() {
        return new CustomOidcUserService();
    }
}

3. 验证KeyCloak客户端配置

  • 确保KeyCloak客户端已开启openid scope,且userinfo端点可正常访问
  • 客户端访问令牌需包含profile、email等读取用户资料的权限(默认配置已包含)

额外优化

若对性能有要求,可给用户信息添加缓存逻辑,比如根据令牌过期时间缓存,避免每次请求都调用/userinfo端点;也可自定义属性映射规则,将KeyCloak中的locale等字段直接映射到OidcUser的对应属性。

内容的提问来源于stack exchange,提问作者Cesar Manuel Cruzata

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 19:24:26