gpt4 book ai didi

java - 无法使用 Google API [google-oauth-java-client-1.12.0-beta] 为服务帐户流获取 token

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:48:51 25 4
gpt4 key购买 nike

我正在使用 Google API(版本 google-oauth-java-client-1.12.0-beta)获取 OAuth2 访问 token ,但返回“invalid_grant”。引用:https://developers.google.com/accounts/docs/OAuth2ServiceAccount

代码如下:

import com.google.api.client.auth.jsontoken.JsonWebSignature;
import com.google.api.client.auth.jsontoken.JsonWebToken;
import com.google.api.client.auth.jsontoken.RsaSHA256Signer;
import com.google.api.client.auth.oauth2.TokenRequest;
import com.google.api.client.auth.oauth2.TokenResponse;
import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.util.Clock;

import java.io.FileInputStream;
import java.io.IOException;

import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;


public class TestClient
{
private static PrivateKey getPrivateKey(String keyFile, String alias, String password)
throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException, UnrecoverableKeyException
{
KeyStore keystore = KeyStore.getInstance("PKCS12");
keystore.load(new FileInputStream(keyFile), password.toCharArray());
PrivateKey privateKey = (PrivateKey) keystore.getKey(alias, password.toCharArray());

return privateKey;
}

public static void main(String[] args)
throws GeneralSecurityException, IOException
{
String password = "notasecret";
String alias = "privatekey";
String keyFile = "<private key file>.p12";
String serviceAccountScopes = "https://www.googleapis.com/auth/urlshortener";
String serviceAccountUser = "user1@gmail.com";
String serviceAccountId = "<a/c id>.apps.googleusercontent.com";
JsonWebSignature.Header header = new JsonWebSignature.Header();
header.setAlgorithm("RS256");
header.setType("JWT");

JsonWebToken.Payload payload = new JsonWebToken.Payload(Clock.SYSTEM);
long currentTime = Clock.SYSTEM.currentTimeMillis();
payload.setIssuer(serviceAccountId)
.setAudience("https://accounts.google.com/o/oauth2/token")
.setIssuedAtTimeSeconds(currentTime / 1000)
.setExpirationTimeSeconds(currentTime / 1000 + 3600)
.setPrincipal(serviceAccountUser);
payload.put("scope", serviceAccountScopes);
System.out.println(payload.toPrettyString());

PrivateKey serviceAccountPrivateKey = getPrivateKey(keyFile, alias, password);
String assertion = RsaSHA256Signer.sign(serviceAccountPrivateKey, getJsonFactory(), header, payload);
TokenRequest request = new TokenRequest(getTransport(), getJsonFactory(), new GenericUrl(getTokenServerEncodedUrl()), "assertion");

request.put("grant_type", "urn:ietf:params:oauth:grant-type:jwt-bearer");
request.put("assertion", assertion);
TokenResponse resp = request.execute();
System.out.println("token : " + resp.getAccessToken());
}

private static String getTokenServerEncodedUrl()
{
return "https://accounts.google.com/o/oauth2/token";
}

private static JsonFactory getJsonFactory()
{
return new JacksonFactory();
}

private static HttpTransport getTransport()
{
return new NetHttpTransport();
}
}

结果:

Exception in thread "main" com.google.api.client.auth.oauth2.TokenResponseException: 400 Bad Request
{
"error" : "invalid_grant"
}
at com.google.api.client.auth.oauth2.TokenResponseException.from(TokenResponseException.java:103)
at com.google.api.client.auth.oauth2.TokenRequest.executeUnparsed(TokenRequest.java:303)
at com.google.api.client.auth.oauth2.TokenRequest.execute(TokenRequest.java:323)

这里有什么问题?任何提示将不胜感激。

最佳答案

在 Google 服务和 Google API 客户端库上使用服务帐户时,您不必自己创建签名和构建 JWT token ,因为有可读的实用程序类,可以通过 OAuth 简单地执行服务帐户授权2.0.

但是,除了 Google 云端硬盘文档外,这方面的文档并不多,其中包含多种编程语言的详细说明和代码示例。你应该阅读: https://developers.google.com/drive/service-accounts#google_apis_console_project_service_accounts

您的代码存在一些问题:

  • 服务帐户的 ID 应采用以下形式:<some-id>@developer.gserviceaccount.com (是的,电子邮件而不是客户 ID,我知道这很奇怪)
  • 你只设置了principal做的时候 Google Apps domain Wide delegation但是您当然不能在 Gmail 帐户上执行此操作,只能在 Google Apps 帐户上执行此操作,管理员已授予您访问其域的权限,因此在您的情况下:不要设置它。

以下是使用 Java 编写的带有服务帐户的 OAuth 2.0 代码示例。

注意:您还需要下载 the URL Shortener library .

/** Email of the Service Account */
private static final String SERVICE_ACCOUNT_EMAIL = "<some-id>@developer.gserviceaccount.com";

/** Path to the Service Account's Private Key file */
private static final String SERVICE_ACCOUNT_PKCS12_FILE_PATH = "/path/to/<public_key_fingerprint>-privatekey.p12";

/**
* Build and returns a URL Shortner service object authorized with the service accounts.
*
* @return URL Shortner service object that is ready to make requests.
*/
public static Drive getDriveService() throws GeneralSecurityException, IOException, URISyntaxException {
HttpTransport httpTransport = new NetHttpTransport();
JacksonFactory jsonFactory = new JacksonFactory();
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(jsonFactory)
.setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
.setServiceAccountScopes(UrlshortenerScopes.URLSHORTENER)
.setServiceAccountPrivateKeyFromP12File(
new java.io.File(SERVICE_ACCOUNT_PKCS12_FILE_PATH))
.build();
Urlshortener service = new Urlshortener.Builder(httpTransport, jsonFactory, null)
.setHttpRequestInitializer(credential).build();
return service;
}

关于java - 无法使用 Google API [google-oauth-java-client-1.12.0-beta] 为服务帐户流获取 token ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14188239/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com