Skip to content

Commit 659d382

Browse files
Timur Sadykovarithmetic1728
andauthored
feat: Returning an issuer claim on request errors (#656)
* logging issuer claim for service account on errors Co-authored-by: arithmetic1728 <58957152+arithmetic1728@users.noreply.github.com>
1 parent 9da437b commit 659d382

File tree

2 files changed

+52
-5
lines changed

2 files changed

+52
-5
lines changed

google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/ServiceAccountCredentials.java

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -609,7 +609,10 @@ public boolean isRequired(HttpResponse response) {
609609
response = request.execute();
610610
} catch (IOException e) {
611611
throw new IOException(
612-
String.format("Error getting access token for service account: %s", e.getMessage()), e);
612+
String.format(
613+
"Error getting access token for service account: %s, iss: %s",
614+
e.getMessage(), getIssuer()),
615+
e);
613616
}
614617

615618
GenericData responseData = response.parseAs(GenericData.class);
@@ -648,7 +651,16 @@ public IdToken idTokenWithAudience(String targetAudience, List<Option> options)
648651
HttpRequestFactory requestFactory = transportFactory.create().createRequestFactory();
649652
HttpRequest request = requestFactory.buildPostRequest(new GenericUrl(tokenServerUri), content);
650653
request.setParser(new JsonObjectParser(jsonFactory));
651-
HttpResponse response = request.execute();
654+
HttpResponse response;
655+
try {
656+
response = request.execute();
657+
} catch (IOException e) {
658+
throw new IOException(
659+
String.format(
660+
"Error getting id token for service account: %s, iss: %s",
661+
e.getMessage(), getIssuer()),
662+
e);
663+
}
652664

653665
GenericData responseData = response.parseAs(GenericData.class);
654666
String rawToken = OAuth2Utils.validateString(responseData, "id_token", PARSE_ERROR_PREFIX);
@@ -755,6 +767,10 @@ public final URI getTokenServerUri() {
755767
return tokenServerUri;
756768
}
757769

770+
private String getIssuer() {
771+
return this.clientEmail;
772+
}
773+
758774
@VisibleForTesting
759775
int getLifetime() {
760776
return lifetime;
@@ -787,7 +803,7 @@ public byte[] sign(byte[] toSign) {
787803
@Override
788804
public JwtCredentials jwtWithClaims(JwtClaims newClaims) {
789805
JwtClaims.Builder claimsBuilder =
790-
JwtClaims.newBuilder().setIssuer(clientEmail).setSubject(clientEmail);
806+
JwtClaims.newBuilder().setIssuer(getIssuer()).setSubject(clientEmail);
791807
return JwtCredentials.newBuilder()
792808
.setPrivateKey(privateKey)
793809
.setPrivateKeyId(privateKeyId)
@@ -862,7 +878,7 @@ String createAssertion(JsonFactory jsonFactory, long currentTime, String audienc
862878
header.setKeyId(privateKeyId);
863879

864880
JsonWebToken.Payload payload = new JsonWebToken.Payload();
865-
payload.setIssuer(clientEmail);
881+
payload.setIssuer(getIssuer());
866882
payload.setIssuedAtTimeSeconds(currentTime / 1000);
867883
payload.setExpirationTimeSeconds(currentTime / 1000 + this.lifetime);
868884
payload.setSubject(serviceAccountUser);
@@ -898,7 +914,7 @@ String createAssertionForIdToken(
898914
header.setKeyId(privateKeyId);
899915

900916
JsonWebToken.Payload payload = new JsonWebToken.Payload();
901-
payload.setIssuer(clientEmail);
917+
payload.setIssuer(getIssuer());
902918
payload.setIssuedAtTimeSeconds(currentTime / 1000);
903919
payload.setExpirationTimeSeconds(currentTime / 1000 + this.lifetime);
904920
payload.setSubject(serviceAccountUser);

google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountCredentialsTest.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1189,6 +1189,37 @@ public void fromStream_noClientEmail_throws() throws IOException {
11891189
testFromStreamException(serviceAccountStream, "client_email");
11901190
}
11911191

1192+
@Test
1193+
public void getIdTokenWithAudience_badEmailError_issClaimTraced() throws IOException {
1194+
MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
1195+
MockTokenServerTransport transport = transportFactory.transport;
1196+
transport.setError(new IOException("Invalid grant: Account not found"));
1197+
ServiceAccountCredentials credentials =
1198+
ServiceAccountCredentials.fromPkcs8(
1199+
CLIENT_ID,
1200+
CLIENT_EMAIL,
1201+
PRIVATE_KEY_PKCS8,
1202+
PRIVATE_KEY_ID,
1203+
SCOPES,
1204+
transportFactory,
1205+
null);
1206+
1207+
String targetAudience = "https://bar";
1208+
IdTokenCredentials tokenCredential =
1209+
IdTokenCredentials.newBuilder()
1210+
.setIdTokenProvider(credentials)
1211+
.setTargetAudience(targetAudience)
1212+
.build();
1213+
1214+
String expectedErrorMessage = String.format("iss: %s", CLIENT_EMAIL);
1215+
1216+
try {
1217+
tokenCredential.refresh();
1218+
} catch (IOException expected) {
1219+
assertTrue(expected.getMessage().contains(expectedErrorMessage));
1220+
}
1221+
}
1222+
11921223
@Test
11931224
public void fromStream_noPrivateKey_throws() throws IOException {
11941225
InputStream serviceAccountStream =

0 commit comments

Comments
 (0)