diff --git a/CHANGELOG.md b/CHANGELOG.md
index 25e44203b..12e9025c8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,22 @@
# Changelog
+## [1.10.0](https://github.com/googleapis/google-auth-library-java/compare/v1.9.0...v1.10.0) (2022-08-05)
+
+
+### Features
+
+* workforce identity federation for pluggable auth ([#959](https://github.com/googleapis/google-auth-library-java/issues/959)) ([7f2c535](https://github.com/googleapis/google-auth-library-java/commit/7f2c535ab7c842a672d6761f4cd80df88e1a37ed))
+
+
+### Bug Fixes
+
+* updates executable response spec for executable-sourced credentials ([#955](https://github.com/googleapis/google-auth-library-java/issues/955)) ([48ff83d](https://github.com/googleapis/google-auth-library-java/commit/48ff83dc68e29dcae07fdea963cbbe5525f86a89))
+
+
+### Documentation
+
+* **samples:** added auth samples and tests ([#927](https://github.com/googleapis/google-auth-library-java/issues/927)) ([32c717f](https://github.com/googleapis/google-auth-library-java/commit/32c717fdf1a721f3e7ca3d75f03fcc229923689c))
+
## [1.9.0](https://github.com/googleapis/google-auth-library-java/compare/v1.8.1...v1.9.0) (2022-08-02)
diff --git a/appengine/pom.xml b/appengine/pom.xml
index 6fff828c5..ecadff5a3 100644
--- a/appengine/pom.xml
+++ b/appengine/pom.xml
@@ -5,7 +5,7 @@
com.google.auth
google-auth-library-parent
- 1.9.1-SNAPSHOT
+ 1.10.1-SNAPSHOT
../pom.xml
diff --git a/bom/pom.xml b/bom/pom.xml
index 77d8f99f4..6c00beddb 100644
--- a/bom/pom.xml
+++ b/bom/pom.xml
@@ -3,7 +3,7 @@
4.0.0
com.google.auth
google-auth-library-bom
- 1.9.1-SNAPSHOT
+ 1.10.1-SNAPSHOT
pom
Google Auth Library for Java BOM
diff --git a/credentials/pom.xml b/credentials/pom.xml
index c1d4f46ff..6048dc662 100644
--- a/credentials/pom.xml
+++ b/credentials/pom.xml
@@ -4,7 +4,7 @@
com.google.auth
google-auth-library-parent
- 1.9.1-SNAPSHOT
+ 1.10.1-SNAPSHOT
../pom.xml
diff --git a/oauth2_http/java/com/google/auth/oauth2/ServiceAccountCredentials.java b/oauth2_http/java/com/google/auth/oauth2/ServiceAccountCredentials.java
index 9b9c99c54..123d72dc0 100644
--- a/oauth2_http/java/com/google/auth/oauth2/ServiceAccountCredentials.java
+++ b/oauth2_http/java/com/google/auth/oauth2/ServiceAccountCredentials.java
@@ -181,6 +181,7 @@ static ServiceAccountCredentials fromJson(
} catch (URISyntaxException e) {
throw new IOException("Token server URI specified in 'token_uri' could not be parsed.");
}
+
if (clientId == null
|| clientEmail == null
|| privateKeyPkcs8 == null
diff --git a/oauth2_http/java/com/google/auth/oauth2/TokenVerifier.java b/oauth2_http/java/com/google/auth/oauth2/TokenVerifier.java
index aed9949b5..12c6af92e 100644
--- a/oauth2_http/java/com/google/auth/oauth2/TokenVerifier.java
+++ b/oauth2_http/java/com/google/auth/oauth2/TokenVerifier.java
@@ -314,17 +314,13 @@ public static class JsonWebKey {
public Map load(String certificateUrl) throws Exception {
HttpTransport httpTransport = httpTransportFactory.create();
JsonWebKeySet jwks;
- try {
- HttpRequest request =
- httpTransport
- .createRequestFactory()
- .buildGetRequest(new GenericUrl(certificateUrl))
- .setParser(OAuth2Utils.JSON_FACTORY.createJsonObjectParser());
- HttpResponse response = request.execute();
- jwks = response.parseAs(JsonWebKeySet.class);
- } catch (IOException io) {
- return ImmutableMap.of();
- }
+ HttpRequest request =
+ httpTransport
+ .createRequestFactory()
+ .buildGetRequest(new GenericUrl(certificateUrl))
+ .setParser(OAuth2Utils.JSON_FACTORY.createJsonObjectParser());
+ HttpResponse response = request.execute();
+ jwks = response.parseAs(JsonWebKeySet.class);
ImmutableMap.Builder keyCacheBuilder = new ImmutableMap.Builder<>();
if (jwks.keys == null) {
@@ -345,7 +341,14 @@ public Map load(String certificateUrl) throws Exception {
}
}
- return keyCacheBuilder.build();
+ ImmutableMap keyCache = keyCacheBuilder.build();
+
+ if (keyCache.isEmpty()) {
+ throw new VerificationException(
+ "No valid public key returned by the keystore: " + certificateUrl);
+ }
+
+ return keyCache;
}
private PublicKey buildPublicKey(JsonWebKey key)
diff --git a/oauth2_http/javatests/com/google/auth/oauth2/MockTokenServerTransport.java b/oauth2_http/javatests/com/google/auth/oauth2/MockTokenServerTransport.java
index 7eea7d462..29c8e6337 100644
--- a/oauth2_http/javatests/com/google/auth/oauth2/MockTokenServerTransport.java
+++ b/oauth2_http/javatests/com/google/auth/oauth2/MockTokenServerTransport.java
@@ -133,6 +133,24 @@ public LowLevelHttpRequest buildRequest(String method, String url) throws IOExce
int questionMarkPos = url.indexOf('?');
final String urlWithoutQuery = (questionMarkPos > 0) ? url.substring(0, questionMarkPos) : url;
final String query = (questionMarkPos > 0) ? url.substring(questionMarkPos + 1) : "";
+
+ if (!responseSequence.isEmpty()) {
+ return new MockLowLevelHttpRequest(url) {
+ @Override
+ public LowLevelHttpResponse execute() throws IOException {
+ try {
+ return responseSequence.poll().get();
+ } catch (ExecutionException e) {
+ Throwable cause = e.getCause();
+ throw (IOException) cause;
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ throw new RuntimeException("Unexpectedly interrupted");
+ }
+ }
+ };
+ }
+
if (urlWithoutQuery.equals(tokenServerUri.toString())) {
return new MockLowLevelHttpRequest(url) {
@Override
diff --git a/oauth2_http/javatests/com/google/auth/oauth2/TokenVerifierTest.java b/oauth2_http/javatests/com/google/auth/oauth2/TokenVerifierTest.java
index 6c6373267..041fbabe4 100644
--- a/oauth2_http/javatests/com/google/auth/oauth2/TokenVerifierTest.java
+++ b/oauth2_http/javatests/com/google/auth/oauth2/TokenVerifierTest.java
@@ -43,6 +43,8 @@
import com.google.api.client.testing.http.MockLowLevelHttpResponse;
import com.google.api.client.util.Clock;
import com.google.auth.http.HttpTransportFactory;
+import com.google.auth.oauth2.GoogleCredentialsTest.MockTokenServerTransportFactory;
+import com.google.auth.oauth2.TokenVerifier.VerificationException;
import com.google.common.io.CharStreams;
import java.io.IOException;
import java.io.InputStream;
@@ -145,7 +147,8 @@ public LowLevelHttpResponse execute() throws IOException {
TokenVerifier.VerificationException exception =
assertThrows(
TokenVerifier.VerificationException.class, () -> tokenVerifier.verify(ES256_TOKEN));
- assertTrue(exception.getMessage().contains("Could not find PublicKey"));
+ assertTrue(
+ exception.getMessage().contains("Error fetching PublicKey from certificate location"));
}
@Test
@@ -186,6 +189,54 @@ public LowLevelHttpResponse execute() throws IOException {
assertTrue(exception.getMessage().contains("Error fetching PublicKey"));
}
+ @Test
+ void verifyPublicKeyStoreIntermittentError() throws IOException, VerificationException {
+ // mock responses
+ MockLowLevelHttpResponse response404 =
+ new MockLowLevelHttpResponse()
+ .setStatusCode(404)
+ .setContentType("application/json")
+ .setContent("");
+
+ MockLowLevelHttpResponse responseEmpty =
+ new MockLowLevelHttpResponse()
+ .setStatusCode(200)
+ .setContentType("application/json")
+ .setContent("{\"keys\":[]}");
+
+ MockLowLevelHttpResponse responseGood =
+ new MockLowLevelHttpResponse()
+ .setStatusCode(200)
+ .setContentType("application/json")
+ .setContent(readResourceAsString("iap_keys.json"));
+
+ // Mock HTTP requests
+ MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
+
+ transportFactory.transport.addResponseSequence(response404, responseEmpty, responseGood);
+
+ TokenVerifier tokenVerifier =
+ TokenVerifier.newBuilder()
+ .setClock(FIXED_CLOCK)
+ .setHttpTransportFactory(transportFactory)
+ .build();
+ TokenVerifier.VerificationException exception =
+ assertThrows(
+ TokenVerifier.VerificationException.class,
+ () -> tokenVerifier.verify(ES256_TOKEN),
+ "Should have failed verification");
+ assertTrue(exception.getMessage().contains("Error fetching PublicKey"));
+
+ exception =
+ assertThrows(
+ TokenVerifier.VerificationException.class,
+ () -> tokenVerifier.verify(ES256_TOKEN),
+ "Should have failed verification");
+ assertTrue(exception.getCause().getMessage().contains("No valid public key"));
+
+ assertNotNull(tokenVerifier.verify(ES256_TOKEN));
+ }
+
@Test
void verifyEs256Token() throws TokenVerifier.VerificationException, IOException {
HttpTransportFactory httpTransportFactory =
diff --git a/oauth2_http/pom.xml b/oauth2_http/pom.xml
index 8aadf3e73..d9bd261b5 100644
--- a/oauth2_http/pom.xml
+++ b/oauth2_http/pom.xml
@@ -5,7 +5,7 @@
com.google.auth
google-auth-library-parent
- 1.9.1-SNAPSHOT
+ 1.10.1-SNAPSHOT
../pom.xml
diff --git a/pom.xml b/pom.xml
index 10171892d..46e761589 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
4.0.0
com.google.auth
google-auth-library-parent
- 1.9.1-SNAPSHOT
+ 1.10.1-SNAPSHOT
pom
Google Auth Library for Java
Client libraries providing authentication and
diff --git a/versions.txt b/versions.txt
index d8f0ea5fd..36266972f 100644
--- a/versions.txt
+++ b/versions.txt
@@ -1,9 +1,9 @@
# Format:
# module:released-version:current-version
-google-auth-library:1.9.0:1.9.1-SNAPSHOT
-google-auth-library-bom:1.9.0:1.9.1-SNAPSHOT
-google-auth-library-parent:1.9.0:1.9.1-SNAPSHOT
-google-auth-library-appengine:1.9.0:1.9.1-SNAPSHOT
-google-auth-library-credentials:1.9.0:1.9.1-SNAPSHOT
-google-auth-library-oauth2-http:1.9.0:1.9.1-SNAPSHOT
+google-auth-library:1.10.0:1.10.1-SNAPSHOT
+google-auth-library-bom:1.10.0:1.10.1-SNAPSHOT
+google-auth-library-parent:1.10.0:1.10.1-SNAPSHOT
+google-auth-library-appengine:1.10.0:1.10.1-SNAPSHOT
+google-auth-library-credentials:1.10.0:1.10.1-SNAPSHOT
+google-auth-library-oauth2-http:1.10.0:1.10.1-SNAPSHOT