in wwauth/Google.Solutions.WWAuth/Adapters/ServiceAccountAdapter.cs [152:212]
public async Task<TokenResponse> ImpersonateAsync(
string stsToken,
IList<string> scopes,
CancellationToken cancellationToken)
{
try
{
this.logger.Info(
"Using STS token to impersonate service account '{0}'",
this.ServiceAccountEmail);
using (var service = new IAMCredentialsService(
new BaseClientService.Initializer()
{
//
// Use the STS token like an access token to authenticate
// requests.
//
HttpClientInitializer = GoogleCredential.FromAccessToken(stsToken),
ApplicationName = UserAgent.Default.ToString()
}))
{
var response = await service.Projects.ServiceAccounts
.GenerateAccessToken(
new GenerateAccessTokenRequest()
{
Scope = scopes
},
$"projects/-/serviceAccounts/{this.ServiceAccountEmail}")
.ExecuteAsync(cancellationToken)
.ConfigureAwait(false);
this.logger.Info(
"Successfully obtained access token for service account '{0}'",
this.ServiceAccountEmail);
return new TokenResponse()
{
AccessToken = response.AccessToken,
ExpiresInSeconds = (long)(DateTime.UtcNow - DateTime.Parse(response.ExpireTime.ToString())).TotalSeconds
};
}
}
catch (GoogleApiException e) when (e.Error?.Code == 403)
{
throw new TokenExchangeException(
$"Insufficient permissions to impersonate service account '{this.ServiceAccountEmail}', " +
$"the principal might be missing the 'Workload Identity User' role", e);
}
catch (GoogleApiException e)
{
this.logger.Error(e,
"Failed to impersonate service account '{0}': {1}, Code: {2}, Details: {3}",
this.ServiceAccountEmail,
e.Message,
e.Error?.Code,
e.Error?.ErrorResponseContent);
throw;
}
}