Я много искал в SO, просматривал множество вопросов относительно одной и той же ошибки, применял все, что они предлагали, но ничего не получилось. Отсюда и здесь.Доступ к Google oAuth, дающий недействительный параметр grant_type (неверный запрос)
Я учусь, как позвонить в Google API (скажем, API календаря Google). Я читаю учебник для разработчиков google от https://developers.google.com/identity/protocols/OAuth2ServiceAccount
Итак, я создал учетную запись службы в Google, созданных учетных данных (я хочу вызывать Google API из своего собственного приложения). После этого я создаю JWT, поместил свой JWT с закрытым ключом, совместно используемым google, и сделав звонок 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 (неверный запрос). Я пробовал то же самое из «Advanced Rest Client клиента Chrome», но результат такой же, недопустимый grant_type (Bad request).
{
error: "invalid_grant"
error_description: "Bad Request"
}
Am отсутствует какой-либо предмет здесь. Пожалуйста, помогите мне
Thanks
проверить эту ссылку https://developers.google.com/analytics/devguides/config/mgmt/v3/mgmtАвторизация, это может быть из-за того, что ваш сервер часы не синхронизируются с протоколом сетевого времени. – SGC
Кроме того, попробуйте изменить область действия и URL-адрес на https://accounts.google.com/o/oauth2/token вместо https://www.googleapis.com/oauth2/v3/token – SGC
@SGC Я не уверен как синхронизировать мой рабочий стол с NTP. В основном я попытался изменить свой часовой пояс машины на PST (и другие) и попробовал то же самое, но ничего не получилось. Я получаю тот же результат. Все работает нормально, если я звоню в API с помощью java-программы вместо REST. В соответствии с моим требованием мне нужно использовать REST –