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

Spring Boot OAuth2资源服务中自动获取用户信息(姓名、邮箱)方案

Spring Boot + Cognito:自动获取用户信息(含缓存)

你不需要硬编码调用UserInfo端点,Spring Security OAuth2提供了内置机制来自动获取并缓存用户信息,以下是两种可行方案:

方案一:自动调用UserInfo端点获取用户信息

Spring Security的OidcUserService(针对OIDC协议,Cognito原生支持)可以自动调用UserInfo端点,并结合Spring Cache实现缓存管理,避免重复请求。

1. 配置application.yml

添加Cognito的核心配置,无需在代码中硬编码端点地址:

spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: https://cognito-idp.${region}.amazonaws.com/${user-pool-id}
        userinfo:
          uri: https://${user-pool-domain}.auth.${region}.amazoncognito.com/oauth2/userinfo
          client-id: ${your-resource-server-client-id}
  • issuer-uri:用于验证JWT签名与有效性,必须和Cognito用户池的 issuer 地址一致
  • userinfo.uri:Cognito官方提供的UserInfo端点地址,通过配置变量动态注入
  • client-id:你在Cognito中创建的资源服务器客户端ID

2. 配置SecurityConfig(含缓存)

启用Spring Cache,并配置带缓存的OIDC用户服务:

@Configuration
@EnableCaching
public class JWTSecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http, OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService) throws Exception {
        http.authorizeRequests(authz -> authz
                .antMatchers(HttpMethod.GET, "/foos/**").hasAuthority("SCOPE_read")
                .antMatchers(HttpMethod.POST, "/foos").hasAuthority("SCOPE_write")
                .anyRequest().authenticated())
            .oauth2ResourceServer(oauth2 -> oauth2
                .jwt(jwt -> jwt.jwtAuthenticationConverter(jwtAuthenticationConverter()))
                .oidcUserService(oidcUserService)); // 绑定自动获取UserInfo的服务
        return http.build();
    }

    // 自定义JWT转换逻辑,合并权限信息
    private JwtAuthenticationConverter jwtAuthenticationConverter() {
        JwtAuthenticationConverter converter = new JwtAuthenticationConverter();
        converter.setJwtGrantedAuthoritiesConverter(new JwtGrantedAuthoritiesConverter());
        return converter;
    }

    // 封装带缓存的OIDC用户服务
    @Bean
    public OAuth2UserService<OidcUserRequest, OidcUser> cachedOidcUserService(CacheManager cacheManager) {
        DefaultOidcUserService delegate = new DefaultOidcUserService();
        // 使用Spring Cache缓存用户信息,缓存名称为userInfoCache
        return new CachingOAuth2UserService<>(delegate, cacheManager.getCache("userInfoCache"));
    }

    // 配置缓存管理器(示例用Caffeine实现)
    @Bean
    public CacheManager cacheManager() {
        CaffeineCacheManager cacheManager = new CaffeineCacheManager("userInfoCache");
        // 缓存有效期与Cognito Access Token默认有效期匹配(1小时)
        cacheManager.setCaffeine(Caffeine.newBuilder()
                .expireAfterWrite(1, TimeUnit.HOURS)
                .maximumSize(1000));
        return cacheManager;
    }
}
  • CachingOAuth2UserService是Spring内置组件,自动缓存UserInfo响应,同一用户的重复请求会直接读取缓存
  • 缓存参数可根据业务需求调整有效期和容量

3. 在业务代码中获取用户信息

通过SecurityContextHolder直接获取认证后的用户属性:

@RestController
public class FooController {

    @GetMapping("/foos/me")
    public Map<String, Object> getCurrentUser() {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        if (auth.getPrincipal() instanceof OidcUser oidcUser) {
            return Map.of(
                    "姓名", oidcUser.getFullName(),
                    "邮箱", oidcUser.getEmail(),
                    "用户ID", oidcUser.getSubject()
            );
        }
        return Collections.emptyMap();
    }
}

方案二:解析ID Token获取用户信息

如果前端能将ID Token传递到后端(比如放在Authorization头中),可以直接解析ID Token获取用户信息,无需调用UserInfo端点——ID Token本身就包含name、email等基础用户属性。

1. 基础Security配置

ID Token本质是JWT,Spring Security可直接验证解析:

@Configuration
public class JWTSecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.authorizeRequests(authz -> authz
                .antMatchers(HttpMethod.GET, "/foos/**").hasAuthority("SCOPE_read")
                .antMatchers(HttpMethod.POST, "/foos").hasAuthority("SCOPE_write")
                .anyRequest().authenticated())
            .oauth2ResourceServer(oauth2 -> oauth2.jwt());
        return http.build();
    }
}

只需确保application.yml中的issuer-uri配置正确,Spring会自动验证ID Token的签名、有效期与受众。

2. 从ID Token提取用户信息

@GetMapping("/foos/me")
public Map<String, Object> getCurrentUser() {
    Authentication auth = SecurityContextHolder.getContext().getAuthentication();
    if (auth.getPrincipal() instanceof Jwt jwt) {
        return Map.of(
                "姓名", jwt.getClaimAsString("name"),
                "邮箱", jwt.getClaimAsString("email"),
                "用户ID", jwt.getClaimAsString("sub")
        );
    }
    return Collections.emptyMap();
}

注意事项

  • 确保Cognito用户池已启用OIDC功能,资源服务器客户端的权限配置正确
  • 使用ID Token方案时,需前端配合传递ID Token,同时注意ID Token的有效期(Cognito默认1小时)
  • 缓存配置可根据业务场景调整,比如针对高频访问用户延长缓存时间

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 00:23:19