无法从Google获取JWT Token,GoogleCredentials.Builder访问受限求助
解决
GoogleCredentials.Builder()受保护无法访问的问题 问题原因
com.google.auth.oauth2.GoogleCredentials.Builder是受保护的抽象内部类,无法直接通过new实例化。这个类的设计逻辑是让具体子类(比如UserCredentials.Builder、ServiceAccountCredentials.Builder)实现构建逻辑,而非直接使用父类Builder。
解决方案
1. 统一依赖版本(避免版本冲突)
先整理pom.xml依赖,确保相关库版本兼容,推荐使用匹配的版本组合:
<dependency> <groupId>com.google.auth</groupId> <artifactId>google-auth-library-oauth2-http</artifactId> <version>1.20.0</version> </dependency> <dependency> <groupId>com.google.api-client</groupId> <artifactId>google-api-client</artifactId> <version>2.2.0</version> </dependency> <dependency> <groupId>com.google.apis</groupId> <artifactId>google-api-services-oauth2</artifactId> <version>v2-rev20240423-2.0.0</version> </dependency> <dependency> <groupId>com.google.api-client</groupId> <artifactId>google-api-client-jackson2</artifactId> <version>2.2.0</version> </dependency>
2. 替换代码实现(两种可选方式)
方式一:使用UserCredentials(用户名密码流,注意Google限制)
如果场景必须用邮箱密码直接获取Token,可使用UserCredentials的Builder:
package JWTToken; import com.google.auth.oauth2.UserCredentials; import com.google.api.client.http.javanet.NetHttpTransport; import com.google.api.client.json.jackson2.JacksonFactory; import java.io.IOException; public class JwtToken { public static void main(String[] args) throws IOException { String clientId = "你的客户端ID"; String clientSecret = "你的客户端密钥"; String username = "你的Google邮箱"; String password = "你的邮箱密码"; // 注意:Google已限制普通账户使用用户名密码流,仅适用于G Suite账户且需开启相关设置 UserCredentials credentials = UserCredentials.newBuilder() .setClientId(clientId) .setClientSecret(clientSecret) .setUsername(username) .setPassword(password) .setTransport(new NetHttpTransport()) .setJsonFactory(new JacksonFactory()) .build(); credentials.refreshIfExpired(); String accessToken = credentials.getAccessToken().getTokenValue(); System.out.println(accessToken); } }
方式二:使用授权码流程(推荐,符合Google OAuth2规范)
用户名密码流存在安全风险且Google限制较多,推荐使用授权码流程获取Token:
package JWTToken; import com.google.api.client.auth.oauth2.Credential; import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow; import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets; import com.google.api.client.http.javanet.NetHttpTransport; import com.google.api.client.json.jackson2.JacksonFactory; import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp; import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver; import com.google.api.client.util.store.FileDataStoreFactory; import java.io.FileReader; import java.io.IOException; import java.util.Collections; public class JwtToken { private static final String TOKENS_DIRECTORY_PATH = "tokens"; private static final String CREDENTIALS_FILE_PATH = "credentials.json"; // 从Google云平台下载的客户端密钥文件 public static void main(String[] args) throws IOException { NetHttpTransport HTTP_TRANSPORT = new NetHttpTransport(); JacksonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance(); // 加载客户端密钥 GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new FileReader(CREDENTIALS_FILE_PATH)); // 创建授权流 GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder( HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, Collections.singleton("https://www.googleapis.com/auth/userinfo.email")) // 按需添加权限范围 .setDataStoreFactory(new FileDataStoreFactory(new java.io.File(TOKENS_DIRECTORY_PATH))) .setAccessType("offline") .build(); // 启动本地服务器接收授权码 LocalServerReceiver receiver = new LocalServerReceiver.Builder().setPort(8888).build(); Credential credential = new AuthorizationCodeInstalledApp(flow, receiver).authorize("user"); String accessToken = credential.getAccessToken(); System.out.println(accessToken); } }
注意事项
- 用户名密码流仅适用于G Suite(Google Workspace)账户,且需在Google Admin控制台开启对应权限或使用应用专用密码。
- 普通Google个人账户建议使用授权码流程,需先在Google云平台创建OAuth2客户端ID并下载
credentials.json文件。
内容的提问来源于stack exchange,提问作者CvMr
相关产品推荐
相关产品推荐

