Как извлечь PrincipalId из Python лямбда на AWS - PullRequest
0 голосов
/ 03 января 2019

Я использую настраиваемый авторизатор для моего сервера без приложения aws.

У меня есть пул cognito user.Рабочий процесс, который я пытаюсь выполнить:

  1. Клиент входит в пул cognito user
  2. Клиент получает токен id_token для будущих вызовов API
  3. Пользователь нажимаетПОЛУЧИТЬ запрос на моей конечной точке API getUserInfo, передавая токен
  4. Лямбда-функция использует токен для проверки а) того, что пользователь вошел в систему, и б) что токен пользователя соответствует user_name, для которого информациязапрашивается

Насколько я понимаю, # 4 может быть достигнуто путем запроса объекта context для атрибута authorizer.principalId на основе этой документации aws.

Однако, когда я тестирую конечную точку, мой объект контекста в лямбда-выражении python не содержит этого свойства authorizer.

Дамп свойства для объекта context из CloudWatch выглядит следующим образом:

{'aws_request_id': 'a37a1735-0ef3-*****-7fb1226218fe', 'log_group_name': '/aws/lambda/****', 'log_stream_name': '2019/01/03/[$LATEST]cca175ae1ff64cb699******', 'function_name': '*****getUser', 'memory_limit_in_mb': '1024', 'function_version': '$LATEST', 'invoked_function_arn': 'arn:aws:lambda:us-east-1:*********getUser', 'client_context': None, 'identity': <__main__.CognitoIdentity object at 0x7f1caf1bbdd8>}

Моя лямбда-Python имеет вид:

def getUser(event, context):
    print(context)
    print(context.__dict__)
    print(context.authorizer)
    print(context.identity.__dict__)
    print(event.__dict__)
    ...

Как я могу заставить свою лямбду извлекать необходимую информацию, чтобы я мог проверить имя пользователя из входящего токена?

Ответы [ 2 ]

0 голосов
/ 04 января 2019

Может быть следующий код поможет вам.

from __future__ import print_function
import boto3
import botocore.exceptions
import hmac
import hashlib
import base64
import json
import uuid
import logging
#Demo pool
USER_POOL_ID='ca-central-1_vaquarkhan'
CLIENT_ID ='vaquarkhanxxxxxxxxxxxxf7h8i9sc7ur6' # replace urs 
CLIENT_SECRET='vaquarkhanbryyyyyyyyyyyyyyyyhlk7ncv85qo5gjia1mdp9'# replace urs 


logger = logging.getLogger()
logger.setLevel(logging.INFO)

client = None

def get_secret_hash(username):
   msg = username + CLIENT_ID
   dig = hmac.new(str(CLIENT_SECRET).encode('utf-8'), 
   msg = str(msg).encode('utf-8'), digestmod=hashlib.sha256).digest()
   d2 = base64.b64encode(dig).decode()
 return d2

ERROR = 0
SUCCESS = 1
USER_EXISTS = 2


def sign_up(username,password):
   try:
     resp = client.sign_up(
         ClientId=CLIENT_ID ,
         SecretHash= get_secret_hash(username),
         Username=username,
         Password=password )
         print(resp)
         #except client.exceptions.UserNotFoundException as e:
         except client.exceptions.UsernameExistsException as e:
    return USER_EXISTS
    except Exception as e:
    print(e)
    logger.error(e)
    return ERROR
  return SUCCESS

def initiate_auth(username, password):
   try:
    # AdminInitiateAuth
      resp = client.admin_initiate_auth(
        UserPoolId=USER_POOL_ID,
        ClientId=CLIENT_ID,
        AuthFlow='ADMIN_NO_SRP_AUTH',
        AuthParameters={
            'USERNAME': username,
            'SECRET_HASH': get_secret_hash(username),
            'PASSWORD': password
          },
         ClientMetadata={
            'username': username,
            'password': password
           })
       except client.exceptions.NotAuthorizedException as e:
      return None, "The username or password incorrect"
    except client.exceptions.UserNotFoundException as e:
    return None, "Unauthorized"
    except Exception as e:
    print(e)
    logger.error(e)
    return None, "Unknown error"
return resp, None

def lambda_handler(event, context):
  global client
  if client == None:
    client = boto3.client('cognito-idp')

   print(event)
   body = event
   username = body['username']
   password = body['password']

   is_new ="false"
   user_id=str(uuid.uuid4())
  signed_up = sign_up(username,password)
  if signed_up == ERROR :
    return {'status':'fail','msg':'failed to sign up'}
  if signed_up == SUCCESS:
    is_new="true"

  resp,msg =initiate_auth(username,password)    

   if msg != None :
      logger.info('failed signIN with username={}'.format(username))
    return {'status':'fail','msg':msg}

id_token =resp['AuthenticationResult']['IdToken']
print('id token: '+id_token)
return {'status': 'success', 'id_token': id_token, 'user_id':user_id,'is_new':is_new}
0 голосов
/ 04 января 2019

Необходимая информация об авторизации доступна лямбда-функции в параметре события. Для этого случая мне нужно было event['requestContext']['authorizer']['cognito:username']

...