我正在使用带有Lambda函数的API网关的新功能来使用自定义授权程序(https://docs.aws.amazon.com/apigateway/latest/developerguide/use-custom-authorizer.html)。
授权人使用 JWT Tokens 来验证当前用户上下文和范围的令牌。一切正常,但有一个关于AWS策略的概念我无法从文档中找到。
自定义授权程序函数的输出必须是包含两个内容的对象:
principalId
- 有问题 policyDocument
- 一个有效的政策文档,其中包含允许用户授权访问Lambda资源,阶段等的语句。现在,自定义授权程序的示例当前显示principalId
变量的几乎任意值。但如果我正确思考,这个principalId
应该对每个用户都是唯一的?并且可能具有与其关联的用户特定唯一值(例如token.userId
或token.email
)。
如果是这样,那么对于我在下面提供的代码,如果JWT令牌不有效,那么我无法访问userId
或email
,并且不知道将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;
}
答案 0 :(得分:6)
principalId旨在表示授权进行API调用的任何实体的长期标识符。因此,如果您有一个现有的用户数据库,则每个用户可能都有一个唯一的标识符或用户名。你提到过用户',这可能很好。从功能上讲,如果启用CloudWatch Logs,则会记录principalId,也可以在映射模板的$ context中访问。
在功能设计方面,您有两种选择来处理“无效”功能。令牌。
如果您返回拒绝访问的有效策略,则可以通过缓存与令牌关联的策略来帮助您再次使用该令牌,从而减少Lambda调用次数。但是,客户可能会收到403并认为该令牌有效但他们无法访问他们所请求的资源。
context.fail("Unauthorized")
会向客户端发送 401 响应错误,这应该向他们表明令牌无效。这将有助于客户端,但如果客户端重复重放坏令牌,也会导致对函数的更多调用。此功能目前无法使用否定缓存,但提供适度保护的另一种方法是使用“身份验证异常”和“#39; identityValidationExpresion' - > http://docs.aws.amazon.com/apigateway/api-reference/resource/authorizer/#identityValidationExpression
此外,我强烈建议您将其迁移到基于apigateway-authorizer-nodejs蓝图的新Lambda函数,因为文档中的代码示例很少,仅用于说明。蓝图有很多注释记录了各种用途,例如失败(" Unauthorized")功能。