【问题标题】:How to provide custom data from API gateway endpoint to lambda authorizer如何从 API 网关端点向 lambda 授权方提供自定义数据
【发布时间】:2019-04-19 11:04:12
【问题描述】:

我们使用的 API 网关端点应通过对特定受众的权限进行限制。

这个想法是使用 lambda 授权器从外部服务获取权限,然后创建策略以允许或拒绝对端点的访问。

为了将权限与 API 端点匹配,端点需要向授权方提供其所需的权限。

我现在的问题是如何使用自己所需的权限来丰富端点数据并在授权者 lambda(可能通过事件)中使用它们以进行进一步验证。

例子:

  • User1 被转发到第一个端点 GET/petstore/pets(此端点需要权限 -> View:Pets
  • Lambda 授权方向外部服务请求用户权限
  • 服务返回:[View:PetsView:Somethingelse等]
  • lambda 授权者将用户权限与所需的端点权限进行匹配,并在匹配时创建允许策略
  • User2做同样的事但没有查看宠物的权限,不匹配->拒绝

这是我的 lambda 代码:

import {Callback, Context} from 'aws-lambda';
import {Authorizer} from './authorizer';

export class App {

    constructor(private authorizer: Authorizer = new Authorizer()) {
    }

    public handleEvent(event, callback: Callback): Promise<void> {
        return this.authorizer.checkAuthorization(event, callback)
            .then((policy) => callback(null, policy))
            .catch((error) => callback(error, null));
    }

}

const app: App = new App();

module.exports.lambda_handler = async (event) => {
    return await app.handleEvent(event);
};

checkAuthorization 方法的代码:

export class Authorizer {


    public resourceAuthorizer: ResourceAuthorizer = new ResourceAuthorizer();
    public authenticationChecker: AuthenticationChecker = new AuthenticationChecker();

    public checkAuthorization(event, callback): Promise<object> {

        const endpointPermissions = event.endpointPermissions;  // <== this is what I need, a custom field in the event which
                                                            // is provided from the api endpoint in some way
                                                            // in my example this whould contain a string or json 
                                                            // with 'View:Pets' and 'View:Somethingelse'

        return this.authenticationChecker.check(event)
            .then((decodedJwt) => {
                const principalId: string = decodedJwt.payload.sub;

            return Promise.resolve(decodedJwt)
                .then((jwt) => this.resourceAuthorizer.check(jwt, event.endpointPermissions))
                .then((payload) => callback(null,
                getAuthorizationPolicy(principalId, 'Allow', event.endpointPermissions, payload)))
                .catch((payload) => callback(null,
                getAuthorizationPolicy(principalId, 'Deny', event.endpointPermissions, payload)));
            }).catch((error) => {
                console.log(error);
                callback('Unauthorized');
            });
    }
}

event.endpointPermissions 基本上就是我要找的。根据 API 端点,这应该填充该端点所需的权限。 resourceAuthorizer 然后从外部服务获取用户权限并将它们与端点权限进行比较,然后创建允许或拒绝策略。

那么我在哪里可以在我的 API Endpoint 中输入 endpointPermissions 以将它们提供给 Authorizer?

【问题讨论】:

  • 如果您有一些代码(即使它是部分伪代码)来展示您想要实现的目标以及您使用的语言,这将有所帮助。
  • 我用代码 sn-ps 更新了问题。

标签: amazon-web-services aws-lambda authorization aws-api-gateway lambda-authorizer


【解决方案1】:

传递给Authorizer的事件包含一个methodArn,格式如下:

arn:aws:execute-api:<Region id>:<Account id>:<API id>/<Stage>/<Method>/<Resource path>

这将为您提供所需的方法和资源路径。它还会为您提供 API 的标识符,但不会提供 API 本身的名称。

API id,可用于通过 AWS 开发工具包获取 API 名称。见here

这应该为您提供构建 endpointPermissions 值所需的一切。

【讨论】:

  • 感谢您的建议。我已经尝试过这个解决方案,它的缺点是您必须创建一个从端点 arn 到我想避免的权限列表的单独映射。
  • 我接受这是正确的答案,因为它绝对可行,尽管不是我想要的。
【解决方案2】:

我无需解析 ARN 就可以解决我的问题,但这非常不合常规:

  1. 在资源的方法请求中,使用权限名称创建 URL 查询字符串参数,并将复选框设置为“必需”

  1. 当从客户端(邮递员)调用请求时,这些强制参数必须作为键提供,它们是特定于端点的。值无关紧要,因为在评估时只会使用键。

  1. 授权方收到的事件现在包含可以评估以供进一步使用的 queryStringParameters。

【讨论】:

    猜你喜欢
    • 2022-12-09
    • 2019-06-29
    • 2019-09-29
    • 1970-01-01
    • 2018-01-15
    • 2023-02-06
    • 1970-01-01
    • 2016-05-29
    • 1970-01-01
    相关资源
    最近更新 更多