Spring OAuth2授权后无法获取UserInfo,自定义OidcUserService未执行
解决Spring OAuth2登录后自定义OidcUserService未调用的问题
我之前也碰到过类似的情况,咱们一步步排查和解决:
一、核心问题:自定义OidcUserService未被正确注入到配置中
最常见的原因是你在configure()方法里没有正确引用Spring容器管理的CustomOidcUserService实例,而是可能直接new了一个对象(这种情况下Spring不会处理里面的@Autowired依赖,也不会替换默认的服务)。
正确的配置方式:
- 确保配置类中注入你的自定义服务:
@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { // 注入Spring管理的CustomOidcUserService实例 @Autowired private CustomOidcUserService oidcUserService; @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .anyRequest().authenticated() .and() .oauth2Login() .userInfoEndpoint() // 这里用注入的实例,而不是new CustomOidcUserService() .oidcUserService(oidcUserService); } }
- 确认
CustomOidcUserService上的@Service注解生效:- 确保该类所在的包被Spring的组件扫描覆盖(比如你的启动类
@SpringBootApplication的包包含这个类的包),否则Spring不会把它注册为Bean。
- 确保该类所在的包被Spring的组件扫描覆盖(比如你的启动类
二、修复updateUser方法中的潜在Bug
你的updateUser方法里有个逻辑错误:userRepository.findByEmail(userInfo.getEmail()).get(); 当数据库中不存在对应用户时,get()会直接抛出NoSuchElementException,后面的if(user == null)永远不会执行。
修改成更安全的写法:
private void updateUser(GoogleOAuth2UserInfo userInfo) { // 用orElseGet避免空指针异常 User user = userRepository.findByEmail(userInfo.getEmail()) .orElseGet(User::new); user.setEmail(userInfo.getEmail()); user.setName(userInfo.getName()); System.out.println(userRepository.save(user)); }
三、其他获取UserInfo的方式
如果自定义服务的方式暂时有问题,你可以直接在控制器中通过@AuthenticationPrincipal注解获取用户信息:
@GetMapping("/current-user") public ResponseEntity<Map<String, Object>> getCurrentUser( @AuthenticationPrincipal OidcUser oidcUser) { // oidcUser.getAttributes()包含了所有从授权服务器获取的用户信息 return ResponseEntity.ok(oidcUser.getAttributes()); }
或者针对非OIDC的OAuth2提供商,使用OAuth2User:
@GetMapping("/current-user") public ResponseEntity<Map<String, Object>> getCurrentUser( @AuthenticationPrincipal OAuth2User oauth2User) { return ResponseEntity.ok(oauth2User.getAttributes()); }
内容的提问来源于stack exchange,提问作者Dmytro
相关产品推荐
相关产品推荐

