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

Spring Boot调用Google Drive API:idToken无效问题求助

问题:Spring Boot调用Google Drive API时idToken验证失败

我通过Spring Boot Java应用实现了Google登录流程,登录时已请求用户授权访问其Google Drive,但用用户的idToken调用Drive API时被拒绝,错误提示:

Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential.

不清楚应该使用哪种token,以及如何获取,附上测试用的控制器代码:

@GetMapping("")
public ResponseEntity<List<String>> listFiles(Authentication authentication) throws IOException,
                                                                                    GeneralSecurityException {
    // 获取已认证用户的idToken
    OAuth2AuthenticationToken oauth2Auth = (OAuth2AuthenticationToken) authentication;
    String idToken = ((DefaultOidcUser) oauth2Auth.getPrincipal()).getIdToken().getTokenValue();
    Credentials credentials = IdTokenCredentials.create(AccessToken.newBuilder().setTokenValue(idToken).build());

    // 构建Drive服务并列出文件
    Drive service = new Drive.Builder(GoogleNetHttpTransport.newTrustedTransport(),
                                      new GsonFactory(),
                                      new HttpCredentialsAdapter(credentials)).setApplicationName(APPLICATION_NAME)
                                                                              .build();
    FileList result = service.files().list().setPageSize(10).setFields("files(name)").execute();
    List<String> fileNames = result.getFiles().stream().map(file -> file.getName()).toList();
    return ResponseEntity.ok(fileNames);
}
解决方案

核心原因

idToken的作用是身份认证,仅用于验证用户身份,无法用来访问Google资源类API(比如Drive)。访问这类API必须使用OAuth2 Access Token,它才是用户授权后,允许应用访问其资源的凭证。

获取Access Token的方法

在Spring Security OAuth2登录流程中,用户完成授权后,OAuth2AuthenticationToken对象中已经包含了Access Token:

  • 直接通过oauth2Auth.getAccessToken()获取OAuth2AccessToken对象,从中提取token值和过期时间。
  • 若Spring Security版本较低,也可以从DefaultOidcUser的属性中提取:oidcUser.getAttributes().get("access_token")

修改后的控制器代码

@GetMapping("")
public ResponseEntity<List<String>> listFiles(Authentication authentication) throws IOException,
                                                                                    GeneralSecurityException {
    OAuth2AuthenticationToken oauth2Auth = (OAuth2AuthenticationToken) authentication;
    // 获取Access Token
    OAuth2AccessToken accessToken = oauth2Auth.getAccessToken();
    String accessTokenValue = accessToken.getTokenValue();

    // 用Access Token创建合法凭证
    Credentials credentials = GoogleCredentials.create(
        new AccessToken(accessTokenValue, accessToken.getExpiresAt())
    );

    // 构建Drive服务并调用API
    Drive service = new Drive.Builder(GoogleNetHttpTransport.newTrustedTransport(),
                                      new GsonFactory(),
                                      new HttpCredentialsAdapter(credentials))
                                      .setApplicationName(APPLICATION_NAME)
                                      .build();
    FileList result = service.files().list()
                             .setPageSize(10)
                             .setFields("files(name)")
                             .execute();
    List<String> fileNames = result.getFiles().stream()
                                   .map(com.google.api.services.drive.model.File::getName)
                                   .toList();
    return ResponseEntity.ok(fileNames);
}

额外注意事项

  • 确保Google Cloud控制台的OAuth2客户端配置中,已添加Drive API的授权范围(例如https://www.googleapis.com/auth/drive.readonly),且用户登录时应用确实请求了这些范围。
  • 如果使用低版本Spring Security,OAuth2AuthenticationToken.getAccessToken()不可用,可改用属性提取方式,同时需手动处理token过期逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 21:07:04