I am trying to use a service account to access Directory API (https://developers.google.com/admin-sdk/directory/v1/reference/users/list). The simplest task is to list users in the organization. That works well with my user account, tested with the OAuth 2.0 Playgorund. But I need to use service account. I am following documentation for two-legged OAuth (https://developers.google.com/identity/protocols/OAuth2ServiceAccount) and implementing REST client in Powershell
- API Access enabled in Google Admin Console
- The service acount is created and P12 credentials downloaded. The account is granted several organization-wide roles in Cloud Console: Browser, Security Reviewer, Organization Viewer - so as to test various scenarios
- Domain-wide authority is granted in the Admin Console, with API scope https://www.googleapis.com/auth/admin.directory.user
Powershell code:
# Forming the JWT claim set
$cert = Get-PfxCertificate -FilePath "c:\ps\GAdmin\apiaccess-123456.p12" -Password (ConvertTo-SecureString "notasecret" -AsPlainText -Force)
$now = (Get-Date).ToUniversalTime()
$createDate = [Math]::Floor([decimal](Get-Date($now) -UFormat "%s"))
$expiryDate = [Math]::Floor([decimal](Get-Date($now.AddHours(1)) -UFormat "%s"))
$rawclaims = [Ordered]@{
iss = "[email protected]"
scope = "https://www.googleapis.com/auth/admin.directory.user"
aud = "https://www.googleapis.com/oauth2/v4/token"
iat = $createDate
exp = $expiryDate
} | ConvertTo-Json
# Encoding the JWT claim set
$jwt = New-Jwt -PayloadJson $rawclaims -Cert $cert -Verbose
# Making the access token request
$apiendpoint = "https://www.googleapis.com/oauth2/v4/token"
$splat = @{
Method = "POST"
Uri = $apiendpoint
ContentType = "application/x-www-form-urlencoded"
Body = "grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=$jwt"
}
$res = Invoke-WebRequest @splat -Verbose
$accesstoken = ($res.content | ConvertFrom-Json).access_token
# Calling Google APIs - list of users
$usersapiendpoint = "https://www.googleapis.com/admin/directory/v1/users?list&customer=my_customer&domain=mydomain.com.au"
$splat = @{
Method = "GET"
Uri = $usersapiendpoint
Headers = @{authorization = "Bearer $accesstoken"}
}
$userlistres = Invoke-WebRequest @splat -Verbose
This results in error:
code 403, "Not Authorized to access this resource/api"
Calling other APIs works. What do I need to do to enable programmatic access to the Directory API? Am I missing a configuration step for the service account/SDK access?
sub = "[email protected]"
to the claim set and now I'm getting another error,"Client is unauthorized to retrieve access tokens using this method."
. I am beginning to think that domain-wide authority is not granted correctly. Not certain how to verify/what to do though. – Svyatoslav Pidgorny