@Override Tuple<ServiceAccountCredentials, BlobInfo> parse(String... args) throws IOException, KeyStoreException, CertificateException, NoSuchAlgorithmException, UnrecoverableKeyException { if (args.length != 4) { throw new IllegalArgumentException(); } KeyStore keystore = KeyStore.getInstance("PKCS12"); keystore.load(Files.newInputStream(Paths.get(args[0])), PASSWORD); PrivateKey privateKey = (PrivateKey) keystore.getKey("privatekey", PASSWORD); ServiceAccountCredentials credentials = ServiceAccountCredentials.newBuilder() .setClientEmail(args[1]) .setPrivateKey(privateKey) .build(); return Tuple.of(credentials, BlobInfo.newBuilder(BlobId.of(args[2], args[3])).build()); }
/** * Initializes OAuth2 credential from a private keyfile, as described in * <a href="https://developers.google.com/api-client-library/java/google-api-java-client/oauth2#service_accounts" * >Service accounts</a>. * * @param serviceAccountEmail Email address of the service account associated with the keyfile. * @param privateKeyFile Full local path to private keyfile. * @param scopes List of well-formed desired scopes to use with the credential. * @return a {@link com.google.auth.Credentials} object. * @throws java.io.IOException if any. * @throws java.security.GeneralSecurityException if any. */ public static Credentials getCredentialFromPrivateKeyServiceAccount( String serviceAccountEmail, String privateKeyFile, List<String> scopes) throws IOException, GeneralSecurityException { PrivateKey privateKey = SecurityUtils.loadPrivateKeyFromKeyStore(SecurityUtils.getPkcs12KeyStore(), new FileInputStream(privateKeyFile), "notasecret", "privatekey", "notasecret"); // Since the user specified scopes, we can't use JWT tokens return ServiceAccountCredentials.newBuilder() .setClientEmail(serviceAccountEmail) .setPrivateKey(privateKey) .setScopes(scopes) .setHttpTransportFactory(getHttpTransportFactory()) .build(); }
@Test public void serviceAccountReplacedWithJwtTokens() throws Exception { ServiceAccountCredentials serviceAccountCredentials = ServiceAccountCredentials.newBuilder() .setClientId("fake-client-id") .setClientEmail("fake@example.com") .setPrivateKeyId("fake-private-key") .setPrivateKey(Mockito.mock(PrivateKey.class)) .build(); PowerMockito.mockStatic(GoogleCredentials.class); Mockito.when(GoogleCredentials.getApplicationDefault()).thenReturn(serviceAccountCredentials); GoogleCredentialsProvider provider = GoogleCredentialsProvider.newBuilder() .setScopesToApply(ImmutableList.of("scope1", "scope2")) .setJwtEnabledScopes(ImmutableList.of("scope1")) .build(); Credentials credentials = provider.getCredentials(); assertThat(credentials).isInstanceOf(ServiceAccountJwtAccessCredentials.class); ServiceAccountJwtAccessCredentials jwtCreds = (ServiceAccountJwtAccessCredentials) credentials; assertThat(jwtCreds.getClientId()).isEqualTo(serviceAccountCredentials.getClientId()); assertThat(jwtCreds.getClientEmail()).isEqualTo(serviceAccountCredentials.getClientEmail()); assertThat(jwtCreds.getPrivateKeyId()).isEqualTo(serviceAccountCredentials.getPrivateKeyId()); assertThat(jwtCreds.getPrivateKey()).isEqualTo(serviceAccountCredentials.getPrivateKey()); }
@Test public void noJwtWithoutScopeMatch() throws Exception { ServiceAccountCredentials serviceAccountCredentials = ServiceAccountCredentials.newBuilder() .setClientId("fake-client-id") .setClientEmail("fake@example.com")
private GoogleCredentials getSourceCredentials() throws IOException { MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory(); PrivateKey privateKey = ServiceAccountCredentials.privateKeyFromPkcs8(SA_PRIVATE_KEY_PKCS8); ServiceAccountCredentials sourceCredentials = ServiceAccountCredentials.newBuilder() .setClientEmail(SA_CLIENT_EMAIL) .setPrivateKey(privateKey) .setPrivateKeyId(SA_PRIVATE_KEY_ID) .setScopes(SCOPES) .setProjectId(PROJECT_ID) .setHttpTransportFactory(transportFactory).build(); transportFactory.transport.addServiceAccount(SA_CLIENT_EMAIL, ACCESS_TOKEN); return sourceCredentials; }
@Test public void createdScoped_clones() throws IOException { PrivateKey privateKey = ServiceAccountCredentials.privateKeyFromPkcs8(SA_PRIVATE_KEY_PKCS8); GoogleCredentials credentials = ServiceAccountCredentials.newBuilder() .setClientId(SA_CLIENT_ID) .setClientEmail(SA_CLIENT_EMAIL) .setPrivateKey(privateKey) .setPrivateKeyId(SA_PRIVATE_KEY_ID) .setScopes(SCOPES) .setServiceAccountUser(SERVICE_ACCOUNT_USER) .setProjectId(PROJECT_ID) .build(); List<String> newScopes = Arrays.asList("scope1", "scope2"); ServiceAccountCredentials newCredentials = (ServiceAccountCredentials) credentials.createScoped(newScopes); assertEquals(SA_CLIENT_ID, newCredentials.getClientId()); assertEquals(SA_CLIENT_EMAIL, newCredentials.getClientEmail()); assertEquals(privateKey, newCredentials.getPrivateKey()); assertEquals(SA_PRIVATE_KEY_ID, newCredentials.getPrivateKeyId()); assertArrayEquals(newScopes.toArray(), newCredentials.getScopes().toArray()); assertEquals(SERVICE_ACCOUNT_USER, newCredentials.getServiceAccountUser()); assertEquals(PROJECT_ID, newCredentials.getProjectId()); assertArrayEquals(SCOPES.toArray(), ((ServiceAccountCredentials)credentials).getScopes().toArray()); }
@Test public void createdDelegated_clones() throws IOException { PrivateKey privateKey = ServiceAccountCredentials.privateKeyFromPkcs8(SA_PRIVATE_KEY_PKCS8); ServiceAccountCredentials credentials = ServiceAccountCredentials.newBuilder() .setClientId(SA_CLIENT_ID) .setClientEmail(SA_CLIENT_EMAIL) .setPrivateKey(privateKey) .setPrivateKeyId(SA_PRIVATE_KEY_ID) .setScopes(SCOPES) .setServiceAccountUser(SERVICE_ACCOUNT_USER) .setProjectId(PROJECT_ID) .build(); String newServiceAccountUser = "stranger@other.org"; ServiceAccountCredentials newCredentials = (ServiceAccountCredentials) credentials.createDelegated(newServiceAccountUser); assertEquals(SA_CLIENT_ID, newCredentials.getClientId()); assertEquals(SA_CLIENT_EMAIL, newCredentials.getClientEmail()); assertEquals(privateKey, newCredentials.getPrivateKey()); assertEquals(SA_PRIVATE_KEY_ID, newCredentials.getPrivateKeyId()); assertArrayEquals(SCOPES.toArray(), newCredentials.getScopes().toArray()); assertEquals(newServiceAccountUser, newCredentials.getServiceAccountUser()); assertEquals(PROJECT_ID, newCredentials.getProjectId()); assertEquals(SERVICE_ACCOUNT_USER, ((ServiceAccountCredentials)credentials).getServiceAccountUser()); }
@Test public void createAssertion_correct() throws IOException { PrivateKey privateKey = ServiceAccountCredentials.privateKeyFromPkcs8(SA_PRIVATE_KEY_PKCS8); List<String> scopes = Arrays.asList("scope1", "scope2"); ServiceAccountCredentials credentials = ServiceAccountCredentials.newBuilder() .setClientId(SA_CLIENT_ID) .setClientEmail(SA_CLIENT_EMAIL) .setPrivateKey(privateKey) .setPrivateKeyId(SA_PRIVATE_KEY_ID) .setScopes(scopes) .setServiceAccountUser(SERVICE_ACCOUNT_USER) .setProjectId(PROJECT_ID) .build(); JsonFactory jsonFactory = OAuth2Utils.JSON_FACTORY; long currentTimeMillis = Clock.SYSTEM.currentTimeMillis(); String assertion = credentials.createAssertion(jsonFactory, currentTimeMillis, null); JsonWebSignature signature = JsonWebSignature.parse(jsonFactory, assertion); JsonWebToken.Payload payload = signature.getPayload(); assertEquals(SA_CLIENT_EMAIL, payload.getIssuer()); assertEquals(OAuth2Utils.TOKEN_SERVER_URI.toString(), payload.getAudience()); assertEquals(currentTimeMillis / 1000, (long) payload.getIssuedAtTimeSeconds()); assertEquals(currentTimeMillis / 1000 + 3600, (long) payload.getExpirationTimeSeconds()); assertEquals(SERVICE_ACCOUNT_USER, payload.getSubject()); assertEquals(Joiner.on(' ').join(scopes), payload.get("scope")); }
@Test public void createAssertion_withTokenUri_correct() throws IOException { PrivateKey privateKey = ServiceAccountCredentials.privateKeyFromPkcs8(SA_PRIVATE_KEY_PKCS8); List<String> scopes = Arrays.asList("scope1", "scope2"); ServiceAccountCredentials credentials = ServiceAccountCredentials.newBuilder() .setClientId(SA_CLIENT_ID) .setClientEmail(SA_CLIENT_EMAIL) .setPrivateKey(privateKey) .setPrivateKeyId(SA_PRIVATE_KEY_ID) .setScopes(scopes) .setServiceAccountUser(SERVICE_ACCOUNT_USER) .setProjectId(PROJECT_ID) .build(); JsonFactory jsonFactory = OAuth2Utils.JSON_FACTORY; long currentTimeMillis = Clock.SYSTEM.currentTimeMillis(); String assertion = credentials.createAssertion(jsonFactory, currentTimeMillis, "https://foo.com/bar"); JsonWebSignature signature = JsonWebSignature.parse(jsonFactory, assertion); JsonWebToken.Payload payload = signature.getPayload(); assertEquals(SA_CLIENT_EMAIL, payload.getIssuer()); assertEquals("https://foo.com/bar", payload.getAudience()); assertEquals(currentTimeMillis / 1000, (long) payload.getIssuedAtTimeSeconds()); assertEquals(currentTimeMillis / 1000 + 3600, (long) payload.getExpirationTimeSeconds()); assertEquals(SERVICE_ACCOUNT_USER, payload.getSubject()); assertEquals(Joiner.on(' ').join(scopes), payload.get("scope")); }