Spring Boot OAuth2 Client对接Google无法获取用户邮箱问题排查
问题现象
用户通过Google登录成功后,回调接口/google返回anonymousUser,SecurityContextHolder.getContext().getAuthentication()获取到的信息为:
AnonymousAuthenticationToken [Principal=anonymousUser, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=null], Granted Authorities=[ROLE_ANONYMOUS]]
相关配置与代码
YAML配置
spring: security: oauth2: client: registration: google: client-id: <client id> client-secret: <client secret> redirect-uri: http://localhost:8080/google scope: - email
控制器代码
@GetMapping("/google") public String googleCallback(@RequestParam("code") String code) { if (code != null) { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); if (authentication != null && authentication.isAuthenticated()) { String email = authentication.getName(); System.out.println(email); return email; } } return "No email"; }
安全配置类
public class SecurityConfiguration implements WebMvcConfigurer { private final JwtFilter jwtFilter; private final DataSource dataSource; @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("http://localhost:4200") .allowedMethods("*"); } @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.csrf().disable(); http.sessionManagement().sessionAuthenticationStrategy(sessionAuthenticationStrategy()); http.authorizeHttpRequests(auth -> auth .requestMatchers("/api/welcome").authenticated() .anyRequest().permitAll() ); http.httpBasic(); http.logout().permitAll(); http.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class); http.oauth2Login(); return http.build(); } }
Google OAuth审核状态
The Trust and Safety team has received your form. They will reach out
to you via your contact email if needed. The review process can take
up to 4-6 weeks. Expect the first email from our Trust and Safety team
within 3-5 days. Your last approved consent screen is still in use.
问题分析与解决步骤
修复YAML配置缩进错误
原配置中scope层级错误,不属于google节点下,导致Google OAuth不会请求email权限,同时影响认证会话传递。修正后的配置:spring: security: oauth2: client: registration: google: client-id: <client id> client-secret: <client secret> redirect-uri: http://localhost:8080/google scope: - email - profile # 建议补充,确保获取完整用户信息调整回调接口的授权规则
当前anyRequest().permitAll()允许匿名访问/google,Spring Security不会将OAuth2认证后的用户信息绑定到该请求上下文。需修改授权规则:http.authorizeHttpRequests(auth -> auth .requestMatchers("/api/welcome").authenticated() .requestMatchers("/google").authenticated() // 要求回调接口必须认证 .anyRequest().permitAll() );优化回调接口的实现方式
建议使用Spring Security OAuth2的默认回调路径(/login/oauth2/code/google),框架会自动完成令牌交换和用户信息获取,无需手动处理code参数:@GetMapping("/login/oauth2/code/google") public String googleCallback(@AuthenticationPrincipal OAuth2User oauth2User) { String email = oauth2User.getAttribute("email"); return email != null ? email : "No email"; }同时YAML的
redirect-uri可改为默认格式:{baseUrl}/login/oauth2/code/{registrationId}排查JWT过滤器的干扰
配置中添加的JwtFilter可能覆盖OAuth2认证后的Authentication对象。如果不需要全局应用JWT过滤,可限制其仅作用于/api/**路径:http.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class) .requestMatchers("/api/**");关于Google审核的影响
根据Google反馈,旧的同意屏幕仍在使用,审核过程不会影响本地测试(只要测试账号在Google Cloud的测试用户列表中),因此问题大概率由代码配置错误导致,无需等待审核完成即可排查修复。
内容的提问来源于stack exchange,提问作者xRay

