无效的补助错误被抛出,而检索的accessToken为谷歌服务帐户请求(Invalid grant

2019-08-08 16:32发布

package com.google.serviceacc;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.SignatureException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.methods.PostMethod;
import org.json.JSONException;
import org.json.JSONObject;
public class GoogleServiceAccount<E> {
    static String keyAlias = "privatekey";

    public static byte[] signData(byte[] data, PrivateKey privateKey) throws InvalidKeyException, SignatureException, NoSuchAlgorithmException
    {
        Signature signature = Signature.getInstance("SHA256withRSA");
        signature.initSign(privateKey);
        signature.update(data);
        return signature.sign();
    }
    /*public static String encodeBase64(byte[] rawData)
    {
        byte[] data = Base64.encodeBase64(rawData);

        return data.toString();
    }*/

    private static PrivateKey getPrivateKey(String keyFile, 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(keyAlias, password.toCharArray());
        return privateKey;
    }
    public static void main(String[] args) throws InvalidKeyException, SignatureException, NoSuchAlgorithmException, UnrecoverableKeyException, KeyStoreException, CertificateException, IOException {
        String keystoreLoc = "C:/Users/xyz/Downloads/b5b400df17628d8.p12";
        String password = "notasecret";
        String jwtStr=null;
        String jwtClaimStr=null;
        PrivateKey privateKey=null;
        JSONObject jwtHeader=new JSONObject();
        try {
            jwtHeader.put("alg","RS256");
            jwtHeader.put("typ","JWT");
            jwtStr= jwtHeader.toString();
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();

        }


        byte[] encodedHeader = Base64.encodeBase64(jwtStr.getBytes("UTF-8"));     
        System.out.println("Original HEaderString: " + jwtStr );
        System.out.println("Base64 Encoded HeaderString : " + new String(encodedHeader));

        JSONObject jwtClaimSet= new JSONObject();
        try {
            jwtClaimSet.put("iss", "client_id_email@developer.gserviceaccount.com");
            jwtClaimSet.put("scope", "https://www.googleapis.com/auth/devstorage.readonly");
            jwtClaimSet.put("aud", "https://accounts.google.com/o/oauth2/token");
            jwtClaimSet.put("exp", "1328554385");
            jwtClaimSet.put("iat", "1328550785");
            jwtClaimStr=jwtClaimSet.toString();
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        byte[]  encodedClaimSet=Base64.encodeBase64(jwtClaimStr.getBytes("UTF-8"));
        System.out.println("Original ClaimSet String:"+jwtClaimStr);
        System.out.println("Base64 Encoded ClaimSet:"+ new String(encodedClaimSet) );

        StringBuffer token = new StringBuffer();
        token.append(Base64.encodeBase64(jwtStr.getBytes("UTF-8")));
        token.append(".");
        token.append(Base64.encodeBase64(jwtClaimStr.getBytes("UTF-8")));

        privateKey= getPrivateKey(keystoreLoc, password);
        byte[] sig = signData(token.toString().getBytes("UTF-8"), privateKey);
        byte[] signedPayload =Base64.encodeBase64(sig);

        token.append(".");
        token.append(signedPayload);

        HttpClient client = new HttpClient();
        PostMethod method = new PostMethod("https://accounts.google.com/o/oauth2/token");
        method.addRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        method.addParameter("grant_type","urn:ietf:params:oauth:grant-type:jwt-bearer");


        System.out.println("printing Token.toString():"+token.toString());

        method.addParameter("assertion",token.toString());
        System.out.println("Printing QuerString:"+method.getQueryString());
        System.out.println("Printing request char set:"+method.getRequestCharSet());
        try {
            int responseCode=client.executeMethod(method);
            System.out.println(responseCode);
            System.out.println(method.getResponseBodyAsString());
            System.out.println(method.getURI());


        } catch (HttpException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }



    }


}

如果我尝试执行上面的代码我”我得到{‘错误’:‘invalid_grant’}当我尝试exute检索的accessToken请求我创建了一个服务帐户,并能够通过上述code.But下载私钥IAM获得授权无效的错误,我需要补充的东西吗?

Answer 1:

我终于得到了输出!!!!

更新的代码是:

package com.voxmobili.sng.cnx.gmail.sync;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.SignatureException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.methods.PostMethod;
import org.json.JSONException;
import org.json.JSONObject;
public class GoogleServiceAccount<E> {
    static String keyAlias = "privatekey";

    public static byte[] signData(byte[] data, PrivateKey privateKey) throws InvalidKeyException, SignatureException, NoSuchAlgorithmException
    {
        Signature signature = Signature.getInstance("SHA256withRSA");
        signature.initSign(privateKey);
        signature.update(data);
        return signature.sign();
    }
      public static String encodeBase64(byte[] rawData)
      {
        byte[] data = Base64.encodeBase64(rawData);

        return data.toString();
      }


    private static PrivateKey getPrivateKey(String keyFile, 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(keyAlias, password.toCharArray());
        return privateKey;
    }


    public static void main(String[] args) throws InvalidKeyException, SignatureException, NoSuchAlgorithmException, UnrecoverableKeyException, KeyStoreException, CertificateException, IOException {
        String keystoreLoc = "C:/Users/xyz/Downloads/b5b400df17628d8.p12";
        String password = "notasecret";
        String jwtHeaderStr=null;
        String jwtClaimStr=null;
        PrivateKey privateKey=null;

        //JWT HEADER
        JSONObject jwtHeader=new JSONObject();
        try {
            jwtHeader.put("alg","RS256");
            jwtHeader.put("typ","JWT");
            jwtHeaderStr=   jwtHeader.toString();
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();

        }


        byte[] encodedHeader = Base64.encodeBase64(jwtHeaderStr.getBytes("UTF-8"));     
        System.out.println("Original HEaderString: " + jwtHeaderStr );
        System.out.println("Base64 Encoded HeaderString : " + new String(encodedHeader));

     //JWT CLAIMSET
        JSONObject jwtClaimSet= new JSONObject();
          long iat =  (System.currentTimeMillis()/1000)-60;
          long exp =  iat + 3600;
        try {
            jwtClaimSet.put("iss", "4459@developer.gserviceaccount.com");
            jwtClaimSet.put("scope", "https://www.googleapis.com/auth/calendar.readonly");
            jwtClaimSet.put("aud", "https://accounts.google.com/o/oauth2/token");
            jwtClaimSet.put("exp", +exp);
            jwtClaimSet.put("iat",+iat);
            jwtClaimStr=jwtClaimSet.toString();
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        byte[]  encodedClaimSet=Base64.encodeBase64(jwtClaimStr.getBytes("UTF-8"));
        System.out.println("Original ClaimSet String:"+jwtClaimStr);
        System.out.println("Base64 Encoded ClaimSet:"+ new String(encodedClaimSet) );

        StringBuffer token = new StringBuffer();
        token.append(new String(encodedHeader));
        token.append(".");
        token.append(new String(encodedClaimSet));

        //JWT SIGNATURE
        privateKey= getPrivateKey(keystoreLoc, password);
        byte[] sig = signData(token.toString().getBytes("UTF-8"), privateKey);
        byte[] encodedSig=Base64.encodeBase64(sig);
        System.out.println("Signature before encoding:"+ new String(encodedSig));
        String signedPayload =encodeBase64(sig);
        //System.out.println("Signature before encoding:"+signedPayload);
        token.append(".");
        //token.append(signedPayload);
        token.append(new String(encodedSig));

        HttpClient client = new HttpClient();
        PostMethod method = new PostMethod("https://accounts.google.com/o/oauth2/token");
        method.addRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        method.addParameter("grant_type","urn:ietf:params:oauth:grant-type:jwt-bearer");


        System.out.println("printing Token.toString():"+token.toString());

        method.addParameter("assertion",token.toString());
        try {
            int responseCode=client.executeMethod(method);
            System.out.println(responseCode);
            System.out.println(method.getResponseBodyAsString());
            System.out.println(method.getURI());


        } catch (HttpException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }



    }


}


文章来源: Invalid grant error is being thrown while retrieving accessToken for Google Service account request