in token-service/src/main/java/com/google/solutions/tokenservice/oauth/WorkloadIdentityPool.java [78:143]
public StsAccessToken issueAccessToken(
IdToken idToken,
String scope
) throws IOException {
Preconditions.checkNotNull(idToken, "idToken");
Preconditions.checkNotNull(scope, "scope");
try {
var client = createStsClient();
var requestBody = new GoogleIdentityStsV1ExchangeTokenRequest()
.setGrantType(GRANT_TYPE)
.setAudience(this.options.audience())
.setScope(scope)
.setRequestedTokenType(ACCESS_TOKEN_TYPE)
.setSubjectToken(idToken.value())
.setSubjectTokenType(ID_TOKEN_TYPE);
//
// The token API returns errors in OAuth format, not in the standard
// Google API error format as the client library expects.
//
// Add hook to extract error details.
//
var request = client.v1().new Token(requestBody) {
@Override
protected GoogleJsonResponseException newExceptionOnError(HttpResponse response) {
try {
var builder = new HttpResponseException.Builder(
response.getStatusCode(),
response.getStatusMessage(),
response.getHeaders());
var errorDetails = client
.getJsonFactory()
.fromInputStream(response.getContent(), TokenErrorDetails.class);
return new GoogleJsonResponseException(builder, errorDetails.toError());
}
catch (IOException e)
{
return super.newExceptionOnError(response);
}
}
};
var issueTime = Instant.now();
var response = request.execute();
return new StsAccessToken(
response.getAccessToken(),
scope,
issueTime,
issueTime.plusSeconds(response.getExpiresIn()));
}
catch (GoogleJsonResponseException e) {
switch (e.getStatusCode()) {
case 400:
throw new IllegalArgumentException(e.getDetails() != null
? e.getDetails().getMessage()
: e.getMessage());
default:
throw (GoogleJsonResponseException) e.fillInStackTrace();
}
}
}