本文介绍了使用无效的grant_type访问Google oAuth(错误的请求)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在这里搜索了很多东西,浏览了许多关于同样错误的问题,应用了他们所建议的任何内容,但没有结果。因此在这里写作。



我正在学习如何拨打Google API(例如Google Calendar API)。我正在阅读来自
的Google开发者教程



所以我在google中创建了一个服务帐户,创建了凭据(我想从我自己的应用程序调用Google API)。之后我创建了JWT,用谷歌共享的私钥给我的JWT打了一针,并且发起了REST POST调用来获得oAuth。这里是我的代码

  public class TestGoogleAPI {

public static void main(String [] args)抛出异常{
String header ={\alg \:\RS256 \,\typ \:\JWT \};
long time = Calendar.getInstance()。getTimeInMillis()/ 1000;

字符串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);

字符串输入= base64Header +。 + base64ClaimSet;

文件f =新文件(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.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,输入+。+ base64Sign);

$ b $ 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(); $(b
$ b)if(conn.getResponseCode()!= 200){
System.out.println(conn.getResponseMessage());
}

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

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

}

)。我试过Chrome的高级休息客户端,但结果是一样的,无效的grant_type(错误的请求)。

  {
错误:invalid_grant
error_description:Bad Request
}

我在这里错过了什么。请帮助我



谢谢

解决方案

最后我得到了解决方案。当我编码头文件和声明集时,我正在执行base64编码,而不是base64safeURL encoidng。在替换之后

  Base64.encodeBase64(some_data); 

with

  Base64.encodeBase64URLSafe(some_data); 

在上述代码中的所有事件中,一切正常。我获取访问令牌并能够使用oAuth令牌来访问Google API


I searched a lot in SO, skim through many questions regarding the same error, applied whatever they suggested, but nothing turned out. Hence writing here.

I am learning how to make a call to Google API (say Google Calendar API). I am going through the google developers tutorial fromhttps://developers.google.com/identity/protocols/OAuth2ServiceAccount

So I have created a service account in the google, created credentials (I want to invoke Google API from my own application). After then I create JWT, singed my JWT with private key shared by google, and making a REST POST call to get the oAuth. Here is my code

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());
}

}

I am getting 400 (Bad request). I tried the same from "Chrome's Advanced Rest Client", but the result is same, invalid grant_type (Bad request).

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

Am I missing any thing here. Please help me

Thanks

解决方案

Finally I got the resolution. When I am encoding header and claimset, I am doing base64 encoding, instead of base64safeURL encoidng. After replacing

Base64.encodeBase64(some_data);

with

Base64.encodeBase64URLSafe(some_data);

at all occurrences in the above code, everything is working fine. I am getting the access token and able to hit the google API with oAuth token

这篇关于使用无效的grant_type访问Google oAuth(错误的请求)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-17 01:02
查看更多