从Google Cloud获取OAuth2 Token时提示账号不存在的问题排查
Google Cloud OAuth2 Token请求报错:账号不存在
请求OAuth2 Token时返回如下错误:
Status Code: HTTP/1.1 400 Bad Request Response: {"error":"invalid_grant","error_description":"Invalid grant: account not found"}
我使用拥有Token生成权限的服务账号,通过以下代码尝试获取Token,采用Apache HttpComponents处理网络请求、io.jsonwebtoken构建JWT。由于对这些库和Java开发不太熟悉,想请教代码中是否存在明显功能性问题:
import io.jsonwebtoken.* import io.jsonwebtoken.security.Keys; import org.apache.commons.codec.binary.Base64 import org.apache.http.client.methods.* import org.apache.http.impl.client.HttpClientBuilder import org.apache.http.entity.StringEntity; import org.apache.http.util.EntityUtils; import java.security.Key; import java.security.PrivateKey import java.util.Base64 import java.util.Base64.Decoder import java.nio.charset.StandardCharsets import java.security.interfaces.* import java.security.KeyFactory import java.security.NoSuchAlgorithmException import java.security.spec.PKCS8EncodedKeySpec import java.security.Key; iss = "serviceacct@project.iam.gserviceaccount.com" // svc account email scope = "https://www.googleapis.com/auth/compute.readonly" // A space-delimited list of the permissions that the application requests. aud = "https://oauth2.googleapis.com/token" // ALWAYS def iat = (System.currentTimeMillis() / 1000).trunc() // // The time the assertion was issued, specified as seconds since 00:00:00 UTC, January 1, 1970. def exp = (System.currentTimeMillis() / 1000 + 1200).trunc() //20 minutes from now // The expiration time of the assertion, specified as seconds since 00:00:00 UTC, January 1, 1970. This value has a maximum of 1 hour after the issued time. //JWT Payload String jsonString = """{"typ":"${iss}", "scope":"${scope}", "aud":"${aud}", "exp":"${exp}", "iat":"${iat}"}"""; // Formatting key StringBuilder pkcs8Lines = new StringBuilder(); BufferedReader rdr = new BufferedReader(new StringReader(BASEKEY)); String line; while ((line = rdr.readLine()) != null) { pkcs8Lines.append(line); } // Cleaning key String pkcs8Pem = pkcs8Lines.toString(); pkcs8Pem = pkcs8Pem.replace("-----BEGIN PRIVATE KEY-----", ""); pkcs8Pem = pkcs8Pem.replace("-----END PRIVATE KEY-----", ""); pkcs8Pem = pkcs8Pem.replaceAll("\\s+",""); // Decoding key byte[] valueDecoded = Base64.decodeBase64(pkcs8Pem); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(valueDecoded); KeyFactory rsaFact = KeyFactory.getInstance("RSA"); RSAPrivateKey key = (RSAPrivateKey) rsaFact.generatePrivate(keySpec); // Generate Token String jwt = Jwts.builder() //JWT Header .setHeaderParam("alg","RS256") .setHeaderParam("typ","JWT") .setPayload(jsonString) .signWith(SignatureAlgorithm.RS256, key) .compact(); def httpClient = HttpClientBuilder.create().build() def httpPost = new HttpPost(aud) String bodystring = "grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion="+"${jwt}" String encodedParams = URLEncoder.encode(bodystring, StandardCharsets.UTF_8); // Encode StringEntity entity = new StringEntity(bodystring) httpPost.setEntity(entity); httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded") def response = httpClient.execute(httpPost) //debug String statusCode = response.getStatusLine() //.getStatusCode(); String content = response.getEntity().getContent().getText() //.getStatusCode(); System.out.println("Status Code: " + statusCode); System.out.println("Response: " + content);
我曾按照Google OAuth2服务账号认证文档调整JWT payload,但问题未解决。另外发现:即使设置请求Content-Type为url编码,调试时entity的Content-Type仍显示为text/plain; charset=ISO-8859-1,后续成功设置entity的Content-Type,但错误依然存在。
内容的提问来源于stack exchange,提问作者Scott MacDonald
相关产品推荐
相关产品推荐

