jwt token from private key file in Java for service-service auth

1,766 views
Skip to first unread message

Taha Sabih

unread,
Nov 13, 2017, 10:57:01 AM11/13/17
to Google Cloud Endpoints
I am trying to setup service to service authentication for my api, and was looking for a way to sign the jwt from the private key file of my service account. The examples here are only in python and I have so far failed to find documentation for doing the same in Java. Any help with how to do this in Java would be appreciated!

-T

lei...@google.com

unread,
Nov 13, 2017, 5:11:49 PM11/13/17
to Google Cloud Endpoints
Currently, the documents at cloud.google.com only provide a Python example code (i.e., the function def generate_jwt(service_account_file)) for signing the JWT using the key file of a service account. 
To sign the JWT from the private key file of a service account in Java, you may try the library "google-auth-library-java" at https://github.com/google/google-auth-library-java. In particular, the function byte[] sign(byte[] toSign) in the link may be useful since it "signs the provided bytes using the private key associated with the service account."  

Taha Sabih

unread,
Nov 14, 2017, 10:35:37 AM11/14/17
to Google Cloud Endpoints
Ended up using a combination of google auth and jjwt to do it. In case someone needs to do it later, here's the code in Java:

// credsStream is the InputStream for the json private key for the service account
ServiceAccountCredentials serviceAccount = ServiceAccountCredentials.fromStream(credsStream);
JwtBuilder jwts = Jwts.builder();
// set header
Map<String, Object> header = new HashMap<>();
header.put("type", "JWT");
header.put("alg", "RS256");
jwts.setHeader(header);
// set claims
Map<String, Object> claims = new HashMap<>();
claims.put("target_audience", "https://echo-api.endpoints.<YOUR_PROJECT_ID>.cloud.goog");
claims.put("exp", System.currentTimeMillis() / 1000 + 3600);
claims.put("iat", System.currentTimeMillis() / 1000);
claims.put("iss", "<SERVICE_ACCOUNT_EMAIL>");
claims.put("aud", "https://www.googleapis.com/oauth2/v4/token");
jwts.addClaims(claims);
// sign with key
jwts.signWith(SignatureAlgorithm.RS256, serviceAccount.getPrivateKey());
// encode base64
String jwt = jwts.compact();

// get jwt from google for your service account
HttpPost httpPost = new HttpPost("https://www.googleapis.com/oauth2/v4/token");

ArrayList<NameValuePair> postParameters = new ArrayList<>();
postParameters.add(new BasicNameValuePair("grant_type", "urn:ietf:params:oauth:grant-type:jwt-bearer"));
// add param for the jwt you got by signing with your private key
postParameters.add(new BasicNameValuePair("assertion", jwt));

CloseableHttpClient httpclient = HttpClients.createDefault();

httpPost.setEntity(new UrlEncodedFormEntity(postParameters, "UTF-8"));
httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");

HttpResponse response = httpclient.execute(httpPost);
// response.getEntity() will now contain the json with an id_token containing the jwt which you can now use to authenticate with your cloud endpoints. 
Reply all
Reply to author
Forward
0 new messages