【问题标题】:Access principalId in lambda function (python) from API Authorizer从 API Authorizer 访问 lambda 函数 (python) 中的 principalId
【发布时间】:2020-10-21 21:22:24
【问题描述】:

我有一个工作正常的 API 授权器,但我想在我的 lambda 函数(用 python 编写)中访问获得的 principalId。 我在其他答案中看到他们建议使用模板映射,但我根本无法让它工作。 我使用以下内容创建了一个简单的映射:

{
    "userId" : "$context.authorizer.principalId"
}

对于内容类型:application/json 并尝试使用这两个选项:

  • 当没有模板匹配请求 Content-Type 标头时
  • 当没有定义模板时(推荐)

但无论如何,当我尝试访问函数上的变量时,它会给我一个 keyError。 我也尝试使用默认为您提供的映射并通过“上下文”访问它,但我也得到一个 keyError。

要访问它,我只需使用:

event["userId"]

event["context"]

但在这两种情况下我都会得到 keyError。

更新 1: 这里的代码仅供参考,函数和授权者在API中都可以正常工作,唯一的问题是当我尝试在函数中获取principalId时。

lambda函数代码:

def handler(event, context):
    print(event['userId'])
    # Your code goes here!
    documento = event.get("documento")
    tipo = event.get("tipo")
    documento_bytes = base64.decodebytes(documento.encode('utf-8'))
    if tipo == "ine":
        return get_info_ine(documento_bytes)
    else:
        respuesta = {
            "estatus" : "ERROR",
            "mensaje" : "El tipo de documento <%s> enviado no existe" % tipo,
            "claveMensaje" : 2
        }
        return respuesta

授权人代码:

import psycopg2
import base64
import re
from perfil import *


def handler(event, context):
    login_string = event["headers"]["Authorization"]
    
    login_string = re.sub('^Basic ', '', login_string)
    username, password = base64.b64decode(
        login_string).decode("UTF-8").split(':')

    connection, cursor = get_connection(hostname, dbuser, dbpass, database)

    cursor.execute("a query here")
    id = 0
    effect = "Deny"
    for record in cursor:
        id = record[0]
        effect = "Allow"

    return {
        "principalId": str(id),
        "policyDocument": {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Action": "execute-api:Invoke",
                    "Effect": effect,
                    "Resource": "arn:aws:execute-api:us-west-2:12345678910:xyz/*/POST/*"
                }
            ]
        }
    }

【问题讨论】:

  • 您查看过事件的字典键了吗?打印 JSON.dumps(event) 可能有助于找到隐藏授权上下文的位置
  • 是的,我做到了,它只显示了请求正文中包含的 json。
  • 你能用 Authorizer 和 lambda 函数代码更新你上面的问题吗?
  • @tsamaya 我做到了,代码在 API 中运行良好,除了尝试获取 principalId 时

标签: aws-lambda lambda-authorizer


【解决方案1】:

据我了解,Authorizer 将来自数据库的用户 ID 放在生成的 Policy 的 PrincipalId 中。

目标是在函数中访问这个id。

授权方附加的策略可以在输入event 对象上找到,其键属性为requestContext。完整路径为:event['requestContext']['authorizer']['principalId']

这是一个简单的 hello 函数,它从其授权方读取(并输出)PrincipalId 值:

def hello(event, context):
    print('event', event)
    userId = None
    if 'requestContext' in event and 'authorizer' in event['requestContext']:
        userId = event['requestContext']['authorizer']['principalId']
    body = {
        "userId": userId,
        "event": event
    }

    response = {
        "statusCode": 200,
        "headers": {
            # Required for CORS support to work
            'Access-Control-Allow-Origin': '*',
            # Required for cookies, authorization headers with HTTPS
            'Access-Control-Allow-Credentials': True,
        },
        "body": json.dumps(body)
    }

    return response

【讨论】:

  • 嗯,最终问题出在我这方面真的很愚蠢。我没有在 API 中部署更改,但是您的回答让我意识到了这一点。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-01-28
  • 2019-05-29
  • 2019-06-10
  • 2018-08-01
  • 2022-07-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多