5

Google アナリティクス API アクセスでリフレッシュ トークンを呼び出すために使用するために、JSON Web トークンを作成しようとしています。私はサービスアカウントアプローチを採用しました。

このアプローチに従って、次のことを行う必要があります。

  1. サービス アカウントの作成
  2. アナリティクス アプリ用に作成したメール アドレスを Google アナリティクス アカウントに追加します。
  3. 秘密鍵ファイル (.p12) をダウンロードします。
  4. このプライベート キーと電子メール アドレスを使用して JWT を構築し、その後、リフレッシュ トークンを取得するために Google 認証サーバーへの HTTP POST 呼び出しを行うために使用されます。

JWT を作成する私のアプローチが正しいかどうかはわかりません。Google Code サイトにあるサンプルJWT_Handler.javaでは、​​ヘッダーと署名部分が欠落しているクレーム部分とリクエスト ペイロードのみを使用して JWT を作成する方法について説明しています。これは、JWT に次の 3 つの部分が含まれるリフレッシュ トークン用の JWT を作成するための Google のガイドラインと混同しています。

  1. JWT ヘッダー
  2. JWT クレーム
  3. サイン

3 つの部分はすべて Base64Url でエンコードされています。次のコードを試しました:

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.nio.charset.Charset;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.Signature;
import java.util.Calendar;
import java.util.Enumeration;

import com.google.api.client.util.Base64;
import com.google.gson.JsonObject;
public class TestJWT {

private final static Charset UTF8_CHARSET = Charset.forName("UTF-8");
private static KeyStore myStore = null;
private static FileInputStream in_cert = null;
public static void main(String[] args) {
    PrivateKey privateKey = null;       
    try {
        in_cert = new FileInputStream(
                "D://Google Analytics//ClientLogin//Analytics//%$%%$%$%-privatekey.p12");

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }       
    try {
        myStore = KeyStore.getInstance("PKCS12");
        myStore.load(in_cert, "notasecret".toCharArray());
        String alias = "";       
        Enumeration objEnumeration = myStore.aliases();
        while (objEnumeration.hasMoreElements() == true) {
            alias = (String) objEnumeration.nextElement();              
            privateKey = (PrivateKey) myStore.getKey(alias,
                    "notasecret".toCharArray());
        }
    } catch (Exception e1) {
        e1.printStackTrace();
    }

    JsonObject header = new JsonObject();
    header.addProperty("alg", "RS256");
    header.addProperty("typ", "JWT");

    Calendar cal = Calendar.getInstance();      
    cal.set(1970, 01, 01);      
    String iat = Long.toString((System.currentTimeMillis() - cal.getTimeInMillis())/1000);
    String exp = Long.toString((System.currentTimeMillis() - cal.getTimeInMillis())/1000 + 60000L);

    JsonObject claim = new JsonObject();
    claim.addProperty("iss", "$$%$^%&^!%@#$@developer.gserviceaccount.com");
    claim.addProperty("scope", "https://www.googleapis.com/auth/devstorage.readonly");
    claim.addProperty("aud", "https://accounts.google.com/o/oauth2/token");
    claim.addProperty("access_type", "offline");
    claim.addProperty("exp", exp);
    claim.addProperty("iat", iat);


    System.out.println("Header : " + header);
    String headerStr = header.toString();
    System.out.println("claim : " + claim);
    String claimStr = claim.toString();


    try {

        byte[] headerArr = headerStr.getBytes(UTF8_CHARSET);
        System.out.println(Base64.encodeBase64String(headerArr));

        byte[] claimArr = claimStr.getBytes(UTF8_CHARSET);
        System.out.println(Base64.encodeBase64String(claimArr));

        String inputStr = Base64.encodeBase64String(headerArr) + "." + Base64.encodeBase64String(claimArr);

        System.out.println("Input String : " + inputStr);
        Signature signature = Signature.getInstance("SHA256withRSA");
        signature.initSign(privateKey);
        signature.update(inputStr.getBytes(UTF8_CHARSET));
        System.out.println("Sign : " + signature.sign());

        System.out.println("Base64url encoded sign : " + Base64.encodeBase64String(signature.sign()));

        System.out.println("Final JWT : " + Base64.encodeBase64String(headerArr) + "." + Base64.encodeBase64String(claimArr) + "." + Base64.encodeBase64String(signature.sign()));

    } catch (Exception e) {
        e.printStackTrace();
    }
}

}
4

1 に答える 1

2

Prathamesh、これはあなたの他の投稿と同じ質問ですか? (スタンドアロン アプリケーションを介して JWT を使用して Java でリフレッシュ トークン リクエストを作成する - Web アプリではありません)

明確にするために、P12 ファイルを使用して JWT に署名すると、(更新トークンではなく) アクセス トークンを取得できます。アクセス トークンは、後続の API 呼び出しを行うために必要なものであるため、問題ありません。

Google の Java クライアント ライブラリを使用して JWT を構築し、署名を行うことを強くお勧めします。これについては、別の投稿で既に適切なサンプルを貼り付けています。

GoogleCredential credentialGA = new GoogleCredential.Builder().setTransport(httpTransport)
        .setJsonFactory(JSON_FACTORY)
        .setServiceAccountId("$#$@#$#$#$@developer.gserviceaccount.com")
        .setServiceAccountScopes(Collections.singleton(AnalyticsScopes.ANALYTICS_READONLY))
        .setServiceAccountPrivateKeyFromP12File(new File("$#$#$%$%$%$-privatekey.p12"))
        .build();
this.analytics = new Analytics.Builder(httpTransport, JSON_FACTORY, credentialGA).setApplicationName("Demo App").build();

クライアント ライブラリを使用したくない特定の理由はありますか? JWT の作成、署名、送信、サービス リクエストの作成、承認ヘッダーの追加、有効期限が切れたときのアクセス トークンの更新などを処理します。

于 2013-11-15T17:35:55.927 に答える