通过 Lambda 的 API 网关自定义授权方的正确委托人 ID 值



我正在使用带有 Lambda 函数的 API 网关的新功能来使用自定义授权方 (https://docs.aws.amazon.com/apigateway/latest/developerguide/use-custom-authorizer.html)。

授权方使用 JWT 令牌来验证当前用户上下文和范围的令牌。一切正常,但有一个关于 AWS 策略的概念,我无法从文档中完全弄清楚。

自定义授权方函数的输出必须是包含两个内容的对象:

  1. principalId - 有问题
  2. policyDocument - 有效的策略文档,其中包含允许用户授权访问 Lambda 资源、阶段等的语句。

现在,自定义授权方的示例当前显示principalId变量的几乎任意值。但是,如果我的想法正确,那么这个principalId对于每个用户来说应该是唯一的吗?并且可能具有与之关联的用户特定唯一值(例如token.userIdtoken.email)。

如果

这是真的,那么对于我在下面提供的代码,如果 JWT 令牌无效,那么我无法访问userIdemail,并且不知道将principalId设置为什么。我暂时将其设置为user只是为了返回拒绝策略以确保响应403 Forbidden

有人对为

自定义授权方设置principalId的最佳实践有任何线索吗?

var jwt = require('jsonwebtoken');
var JWT_SECRET = 'My$ecret!';

/**
 * Implicit AWS API Gateway Custom Authorizer. Validates the JWT token passed
 * into the Authorization header for all requests.
 * @param  {Object} event   [description]
 * @param  {Object} context [description]
 * @return {Object}         [description]
 */
exports.handler = function(event, context) {
  var token = event.authorizationToken;
  try {
    var decoded = jwt.verify(token, JWT_SECRET);
    context.done(null, generatePolicy(decoded.id, 'Allow', 'arn:aws:execute-api:*:*:*'));
  } catch(ex) {
    console.error(ex.name + ": " + ex.message);
    context.done(null, generatePolicy('user', 'Deny', 'arn:aws:execute-api:*:*:*'));
  }
};
function generatePolicy(principalId, effect, resource) {
  var authResponse = {};
  authResponse.principalId = principalId;
  if (effect && resource) {
    var policyDocument = {};
    policyDocument.Version = '2012-10-17'; // default version
    policyDocument.Statement = [];
    var statementOne = {};
    statementOne.Action = 'execute-api:Invoke'; // default action
    statementOne.Effect = effect;
    statementOne.Resource = resource;
    policyDocument.Statement[0] = statementOne;
    authResponse.policyDocument = policyDocument;
  }
  return authResponse;
}

principalId 旨在表示被授权进行 API 调用的任何实体的长期标识符。因此,如果您有一个现有的用户数据库,则每个用户可能都有一个唯一的标识符或用户名。你提到了"用户",这可能很好。从功能上讲,如果您启用 CloudWatch Logs,则会记录 principalId,并且您也可以在映射模板的$context中访问该 Id。

在函数设计方面,有两个选项来处理"无效"令牌。

  1. 如果您返回拒绝访问的有效策略,这将通过缓存与令牌关联的策略来帮助您,以防再次使用,从而减少 Lambda 调用。但是,客户端可能会收到 403 并认为令牌有效,但他们无权访问他们请求的资源。

  2. context.fail("Unauthorized") 将向客户端发送错误的 401 响应,这应该向他们指示令牌无效。这将对客户端有所帮助,但如果客户端反复重播错误令牌,也会导致对函数的更多调用。负缓存目前在该功能上不可用,但提供中等保护的另一种方法是使用"identityValidationExpresion"-> http://docs.aws.amazon.com/apigateway/api-reference/resource/authorizer/#identityValidationExpression

此外,我强烈建议您将其迁移到基于 apigateway-authorizer-nodejs 蓝图的新 Lambda 函数,因为文档中的代码示例很少,仅用于说明。该蓝图有很多注释,记录了各种用途,例如 fail("未经授权")功能。

相关内容

  • 没有找到相关文章

最新更新