Используя Python и создавая свой собственный JWT с использованием методологии HTTP / Rest, я просто не могу заставить делегирование работать.
С одной стороны, в документации по устранению неполадок Google JWT говорится, что ISS должен быть таким же как SUB (учетная запись службы).
Однако на документации сервера oauth2 от сервера к серверу указано, что для олицетворения учетной записи вспомогательной должна быть учетная запись, которую я пытаюсь олицетворять в заявлении.
Нет необходимости говорить, что, несмотря на включение делегирования на уровне домена, добавление правильных областей действия и т. Д. c, я получаю только 403 при попытке получить доступ к домену пользователя с использованием библиотеки запросов в python со следующим пример:
> requests.get("https://www.googleapis.com/admin/directory/v1/users/useremail@/
> google.org",headers={'Authorization':f' Bearer {oauth2tokenhere}'})
Вот пример моей претензии:
> claim = { "iss": 'serviceaccountemail',
> 'sub': 'impersonatedaccountemail',
> 'scope': 'https://www.googleapis.com/auth/admin.directory.user.readonly',
> 'exp': ((datetime.datetime.today() + datetime.timedelta(minutes=60)).timestamp()),
> 'iat': ((datetime.datetime.today()).timestamp()),
> 'aud': "https://oauth2.googleapis.com/token"
> }
Приведенная выше претензия приведет к генерализованной ошибке предоставления (мило, но не полезно).
Если я изменяю утверждение и проверяю, что sub и iss совпадают, генерируется oauth2token, но я получаю ошибку 403 при попытке попасть в API.
Вот документация oauth2 от сервера к серверу, в которой указано, что sub должен быть учетной записью, которую учетная запись службы пытается олицетворять.
https://developers.google.com/identity/protocols/OAuth2ServiceAccount
Вот статья об устранении неполадок, описывающая ISS / Sub был тем же (хотя статья об облаке - самая близкая релевантная топи c, которую я мог найти)
https://cloud.google.com/endpoints/docs/openapi/troubleshoot-jwt
РЕДАКТИРОВАТЬ:
Я использую информацию учетной записи службы из загруженного файла. json, который загружается при создании файла учетной записи службы.
import json as j
import datetime
import jwt
import requests
#creates the claim, 'secret' (from the private key), and the kid, from the service account file, and returns these values in a tuple.
#the tuple can then be used to make dependable positional argument entries to the parameters of the createJWT function.
def create_claim_from_json(self,objpath,scope=["https://www.googleapis.com/auth/admin.directory.user.readonly" "https://www.googleapis.com/auth/admin.directory.user"]):
with open(f'{objpath}','r') as jobj:
data = j.load(jobj)
claim = {
"iss": str(data['client_id']),
"sub": str(data['client_id']),
"scope": str(scope),
"exp": ((datetime.datetime.today() + datetime.timedelta(minutes=59)).timestamp()),
"iat": ((datetime.datetime.today()).timestamp()),
"aud": "https://oauth2.googleapis.com/token"
}
private_key = data['private_key']
kid = {"kid": f"{data['private_key_id']}"}
return claim, private_key, kid
#assembles the JWT using the claim, secret (Private key from the Service account file), the kid value, and the documented RS256 alg.
#returns the completed JWT object back to be used to send to the oauth2 endpoint
#the JWT will be used in the function call retrieve_oauth2token.
def createJWT(self, claim, secret, kid, alg='RS256'):
encoded_jwt = (jwt.encode(claim, secret, alg, kid)).decode('UTF-8')
return encoded_jwt
#Using the JWT created in memory, sends the JWT to the googleapi oauth2 uri and returns a token
def retrieve_oauth2token(self, jwt):
oauth2 = requests.post(f'https://oauth2.googleapis.com/token?grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant- type%3Ajwt-bearer&assertion={jwt}')
oauth2=oauth2.json()
return oauth2 #['access_token'], oauth2['token_type']