【问题标题】:Accessing Google oAuth giving invalid grant_type (Bad request)访问 Google oAuth 提供无效的 grant_type(错误请求)
【发布时间】:2015-12-31 08:50:13
【问题描述】:

我在 SO 中进行了很多搜索,浏览了许多关于同一错误的问题,应用了他们建议的任何内容,但结果一无所获。所以写到这里。

我正在学习如何调用 Google API(比如 Google Calendar API)。我正在浏览谷歌开发者教程 https://developers.google.com/identity/protocols/OAuth2ServiceAccount

所以我在 google 中创建了一个服务帐户,创建了凭据(我想从我自己的应用程序中调用 Google API)。之后,我创建了 JWT,使用 google 共享的私钥对我的 JWT 进行了签名,并进行了 REST POST 调用以获取 oAuth。这是我的代码

public class TestGoogleAPI {

public static void main(String[] args) throws Exception{
    String header = "{\"alg\":\"RS256\",\"typ\":\"JWT\"}";
    long time = Calendar.getInstance().getTimeInMillis()/1000;

    String claimSet = "{\"iss\":\"xxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com\"," +
                "\"scope\":\"https://www.googleapis.com/auth/calendar\"," +
                "\"aud\":\"https://www.googleapis.com/oauth2/v3/token\"," +
                "\"exp\":"+ (time+3600) +"," +
                "\"iat\":" + time +"}";


    String base64Header = new String(Base64.encodeBase64(header.getBytes()),"UTF-8");
    String base64ClaimSet = new String(Base64.encodeBase64(claimSet.getBytes()),"UTF-8");

    String input = base64Header + "." + base64ClaimSet;

    File f = new File("D:/downloads/privatekey.txt");
    FileInputStream fis = new FileInputStream(f);
    DataInputStream dis = new DataInputStream(fis);
    byte[] keyBytes = new byte[(int)f.length()];
    dis.readFully(keyBytes);
    dis.close();
    byte[] key = Base64.decodeBase64(keyBytes);

    PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(key);
    KeyFactory kf = KeyFactory.getInstance("RSA");
    PrivateKey privatekey =  kf.generatePrivate(spec);

    Signature signature = Signature.getInstance("SHA256withRSA"); 
    signature.initSign(privatekey);
    signature.update(input.getBytes());
    String base64Sign = new String(Base64.encodeBase64(signature.sign()),"UTF-8");

    doHttpPost("https://www.googleapis.com/oauth2/v3/token", input + "." + base64Sign);
}

public static void doHttpPost(String urlStr, String assertion) throws Exception{
    URL url = new URL(urlStr);
      HttpURLConnection conn = (HttpURLConnection) url.openConnection();
      conn.setRequestMethod("POST");
      conn.setDoOutput(true);
      conn.setDoInput(true);
      conn.setUseCaches(false);
      conn.setAllowUserInteraction(false);
      conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

      OutputStream out = conn.getOutputStream();
      Writer writer = new OutputStreamWriter(out, "UTF-8");
      writer.write("grant_type");
      writer.write("=");
      writer.write(URLEncoder.encode("urn:ietf:params:oauth:grant-type:jwt-bearer", "UTF-8"));
      writer.write("&");
      writer.write("assertion");
      writer.write("=");
      writer.write(URLEncoder.encode(assertion, "UTF-8"));
      writer.close();
      out.close();

      if (conn.getResponseCode() != 200) {
          System.out.println(conn.getResponseMessage());
      }

      BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
      StringBuilder sb = new StringBuilder();
      String line;
      while ((line = rd.readLine()) != null) {
        sb.append(line);
      }
      rd.close();

      conn.disconnect();
      System.out.println(sb.toString());
}

}

我收到 400(错误请求)。我从“Chrome 的 Advanced Rest Client”中尝试了相同的方法,但结果是相同的,无效的 grant_type(错误请求)。

{
   error: "invalid_grant"
   error_description: "Bad Request"
}

我在这里有什么遗漏吗?请帮帮我

谢谢

【问题讨论】:

标签: java oauth google-api google-calendar-api google-oauth


【解决方案1】:

我终于得到了解决方案。当我对标头和声明集进行编码时,我正在进行 base64 编码,而不是 base64safeURL 编码。替换后

Base64.encodeBase64(some_data);

Base64.encodeBase64URLSafe(some_data);

在上述代码中的所有情况下,一切正常。我正在获取访问令牌并能够使用 oAuth 令牌访问 google API

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-06
    • 2012-05-23
    • 1970-01-01
    • 2014-02-11
    • 2017-12-01
    • 2011-08-17
    • 2013-07-21
    相关资源
    最近更新 更多