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
相关产品推荐
相关产品推荐

