我正在使用 API Gateway 的一项新功能和 Lambda 函数来使用 Custom Authorizer (https://docs.aws.amazon.com/apigateway/latest/developerguide/use-custom-authorizer.html) .
授权者使用 JWT 令牌 验证当前用户上下文和范围的令牌。一切工作正常,但有一个关于 AWS 策略的概念我无法从文档中完全弄清楚。
“Custom Authorizer”函数的输出必须是一个包含两件事的对象:
principalId
有问题
policyDocument
principalId
变量的几乎任意值。但如果我的想法正确的话,这个
principalId
对于每个用户来说应该是唯一的?也许有一个与之相关的用户特定的唯一值(例如 token.userId
或 token.email
)。 如果这是真的,那么对于我下面提供的代码,如果 JWT 令牌not
有效,那么我无权访问userId
或
email
,并且不知道如何设置principalId
到。我暂时将其设置为 user
只是为了获得 Deny政策的回报,以确保响应为
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;
}
在函数设计方面,您有两种选择来处理“无效”令牌。
context.fail("Unauthorized")
将向客户端发送
401错误响应,这应该向他们表明令牌无效。这将对客户端有所帮助,但如果客户端重复重放错误令牌,也会导致对该函数进行更多调用。该功能当前不提供负缓存,但提供适度保护的另一种方法是使用 'identityValidationExpresion' -> http://docs.aws.amazon.com/apigateway/api-reference/resource/authorizer/#身份验证表达式
的新 Lambda 函数,因为文档中的代码示例很少且仅用于说明。该蓝图有很多注释,记录了各种用途,例如失败(“未经授权”)功能。