用Java创建JSON Web令牌 [英] Creating JSON Web Token in Java

查看:78
本文介绍了用Java创建JSON Web令牌的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个JSON Web令牌,以便将其用于通过Google Analytics(分析)API访问进行刷新令牌调用.我已经采取了服务帐户的方式.

I am trying to create a JSON Web Token in order to use it for making refresh token call with Google Analytics API access. I have taken service account approach.

按照这种方法,我需要:

As per this approach I need to :

  1. 创建服务帐户
  2. 使用Google Analytics(分析)帐户添加为Analytics(分析)应用创建的电子邮件地址.
  3. 下载主密钥文件(.p12)
  4. 使用此私钥和电子邮件地址来构造JWT,随后将其用于对google auth服务器进行HTTP POST调用,以获取刷新令牌.

我不确定我创建JWT的方法是否正确.在Google Code网站上以JWT_Handler.java形式提供的示例讨论了如何创建具有索赔部分的JWT,并仅在缺少标头和签名部分的情况下请求有效负载.这与Google为刷新令牌创建JWT的准则相混淆,其中JWT涉及三个部分:

I am not sure whether my approach of creating JWT is correct or not. The sample available as JWT_Handler.java on the Google Code site talks about creating JWT with claim part and request payload only with header and signature part missing. This is confusing with googles guidelines for creating JWT for refresh token where the JWT involves three parts :

  1. JWT标头
  2. JWT索赔
  3. 签名

所有这三个部分都是Base64Url编码的.我尝试了以下代码:

All the three parts are Base64Url encoded. I tried following code :

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

}

推荐答案

Prathamesh,这是与您其他帖子相同的问题吗? (进行刷新令牌请求通过独立应用程序-而不是Web应用程序通过Java与JWT )

Prathamesh, is this the same question as your other post? (Making Refresh Token Request In Java With JWT through a stand alone application - Not a Web App)

为澄清起见,使用P12文件签名JWT将使您获得访问令牌(而不是刷新令牌).可以,因为访问令牌是进行后续API调用所需要的.

To clarify, signing a JWT using the P12 file will let you get an access token (not a refresh token). That's OK, because an access token is what you need to make a subsequent API call.

我强烈建议使用Google的Java客户端库来构建JWT并进行签名,您已经在另一篇文章中为其粘贴了一个很好的示例:

I strongly suggesting using Google's Java client library to construct the JWT and do the signing, of which you already pasted a good sample for in the other post:

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,对其进行签名,发送,构建服务请求,添加授权标头,在过期时刷新访问令牌等.

Is there a specific reason you don't want to use the client library? It will take care of creating the JWT, signing it, sending it, buildng the service requests, adding authorization headers, refreshing the access token when it expires etc etc.

这篇关于用Java创建JSON Web令牌的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆