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

Spring Security中Cognito JWT转换为数据库自定义用户对象的实现问题

实现方案

步骤1:自定义JWT认证转换器

Spring Security OAuth2资源服务器默认会将校验通过的JWT转换为JwtAuthenticationToken,其中principal为JWT对象本身。我们自定义转换器替换该逻辑,在转换阶段从数据库查询你自己的User对象作为principal。

@Component
public class CustomCognitoJwtConverter extends JwtAuthenticationConverter {

    private final UserRepository userRepository;

    public CustomCognitoJwtConverter(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Override
    protected AbstractAuthenticationToken convert(Jwt jwt) {
        JwtAuthenticationToken defaultToken = (JwtAuthenticationToken) super.convert(jwt);
        // 获取Cognito返回的用户ID,对应JWT中的cognito:username声明
        String cognitoUserId = defaultToken.getName();
        // 从本地数据库查询对应的自定义用户
        User user = userRepository.findByCognitoUserId(cognitoUserId)
                // 可根据业务需求调整不存在时的处理逻辑,比如自动创建新用户
                .orElseThrow(() -> new UsernameNotFoundException("未找到对应用户: " + cognitoUserId));
        // 生成新的认证对象,保留原有权限信息,将自定义User作为principal
        return new UsernamePasswordAuthenticationToken(user, defaultToken.getCredentials(), defaultToken.getAuthorities());
    }
}

步骤2:配置Spring Security使用自定义转换器

在安全配置类中将自定义转换器注册到JWT资源服务器配置中:

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    private final CustomCognitoJwtConverter customJwtConverter;

    public SecurityConfig(CustomCognitoJwtConverter customJwtConverter) {
        this.customJwtConverter = customJwtConverter;
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .authorizeHttpRequests(auth -> auth
                        .anyRequest().authenticated()
                )
                .oauth2ResourceServer(oauth2 -> oauth2
                        .jwt(jwt -> jwt
                                .jwtAuthenticationConverter(customJwtConverter)
                        )
                );
        return http.build();
    }
}

步骤3:接口中直接注入使用

完成上述配置后即可在接口中通过@AuthenticationPrincipal直接注入自定义User对象,注意你示例代码中存在笔误,参数名为user,返回值不要调用不存在的principal变量:

@GetMapping("/hello")
public String index(@AuthenticationPrincipal User user) {
    return "Greetings from Spring Boot!" + user.getUserName();
}

注意事项

  • 若业务允许Cognito新用户首次登录自动创建本地账号,可以在查询不到用户时新增写入逻辑,无需直接抛出异常。
  • 如果需要在业务中使用JWT的原始声明,可以将JWT对象存入自定义User类的属性中。
  • 如果需要使用Spring Security的权限校验能力,可以让自定义User类实现UserDetails接口,配置对应的权限字段即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 16:06:13