Created
January 27, 2017 11:21
-
-
Save binshi/bce40ca171ac4ac00b01d9a27bb44926 to your computer and use it in GitHub Desktop.
Simple class to get access token based on service key
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.{IOException, StringReader, Reader, ByteArrayInputStream} | |
import java.nio.charset.Charset | |
import java.security.{NoSuchAlgorithmException, KeyFactory, PrivateKey} | |
import java.security.spec.{InvalidKeySpecException, PKCS8EncodedKeySpec} | |
import java.util.Collections | |
import com.google.api.client.json.webtoken.{JsonWebToken, JsonWebSignature} | |
import com.google.api.client.json.{JsonFactory, GenericJson, JsonObjectParser} | |
import com.google.api.client.json.jackson2.JacksonFactory | |
import com.google.api.client.util.{SecurityUtils, PemReader, Joiner} | |
import com.google.api.services.androidpublisher.AndroidPublisherScopes | |
class ServiceAccountApiAccess { | |
val jsonKey = """{ | |
"type": "service_account", | |
"project_id": "project-XXXXXXX", | |
"private_key_id": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", | |
"private_key": "-----BEGIN PRIVATE KEY-----\nXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n-----END PRIVATE KEY-----\n", | |
"client_email": "[email protected]", | |
"client_id": "zzzzzzzzzzzzzzzzzzzzzzzzzzzz", | |
"auth_uri": "https://accounts.google.com/o/oauth2/auth", | |
"token_uri": "https://accounts.google.com/o/oauth2/token", | |
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", | |
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/[email protected]" | |
} """ | |
val credentialStream = new ByteArrayInputStream(jsonKey.getBytes()) | |
val parser: JsonObjectParser = new JsonObjectParser(JacksonFactory.getDefaultInstance()) | |
val fileContents: GenericJson = parser.parseAndClose(credentialStream, Charset.forName("UTF-8"), classOf[GenericJson]) | |
val clientId: String = fileContents.get("client_id").asInstanceOf[String] | |
val clientEmail: String = fileContents.get("client_email").asInstanceOf[String] | |
val privateKeyPem: String = fileContents.get("private_key").asInstanceOf[String] | |
val privateKeyId: String = fileContents.get("private_key_id").asInstanceOf[String] | |
val privateKey: PrivateKey = privateKeyFromPkcs8(privateKeyPem) | |
val header: JsonWebSignature.Header = new JsonWebSignature.Header | |
header.setAlgorithm("RS256") | |
header.setType("JWT") | |
header.setKeyId(privateKeyId) | |
val payload: JsonWebToken.Payload = new JsonWebToken.Payload | |
val currentTime: Long = System.currentTimeMillis() | |
payload.setIssuer(clientEmail) | |
payload.setAudience("https://www.googleapis.com/oauth2/v4/token") | |
payload.setIssuedAtTimeSeconds(currentTime / 1000) | |
payload.setExpirationTimeSeconds(currentTime / 1000 + 3600) | |
payload.setSubject(null) | |
payload.put("scope", Joiner.on(' ').join(Collections.singleton(AndroidPublisherScopes.ANDROIDPUBLISHER))) | |
val jsonFactory: JsonFactory = JacksonFactory.getDefaultInstance | |
try{ | |
var assertion: String = JsonWebSignature.signUsingRsaSha256(privateKey, jsonFactory, header, payload) | |
println(assertion) | |
}catch { | |
case ex:Exception => ex.printStackTrace() | |
} | |
def privateKeyFromPkcs8(privateKeyPem: String):PrivateKey = { | |
val reader: Reader = new StringReader(privateKeyPem) | |
val section: PemReader.Section = PemReader.readFirstSectionAndClose(reader, "PRIVATE KEY") | |
if (section == null) { | |
throw new IOException("Invalid PKCS8 data.") | |
} | |
val bytes: Array[Byte] = section.getBase64DecodedBytes | |
val keySpec: PKCS8EncodedKeySpec = new PKCS8EncodedKeySpec(bytes) | |
var unexpectedException: Exception = null | |
try { | |
val keyFactory: KeyFactory = SecurityUtils.getRsaKeyFactory | |
val privateKey: PrivateKey = keyFactory.generatePrivate(keySpec) | |
privateKey | |
} | |
catch { | |
case exception: NoSuchAlgorithmException => { | |
unexpectedException = exception | |
} | |
case exception: InvalidKeySpecException => { | |
unexpectedException = exception | |
} | |
} | |
val keyFactory: KeyFactory = SecurityUtils.getRsaKeyFactory | |
val privateKey: PrivateKey = keyFactory.generatePrivate(keySpec) | |
privateKey | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment