[英]Unable to use custom authorizer in API Gateway
我花了几天时间尝试使用带有 auth0 服务的自定义授权方来保护我的 API 网关。 我有我的 lambda 来验证我的持有者令牌,如果我在 AWS 控制台内调用它,Lambda 确实有效,当我创建自定义授权方时,我可以使用持有者令牌成功进行测试。
当我尝试将授权方附加到我的 API 网关方法并使用 postman 和 auth0 提供的令牌测试请求时,它始终返回 401 状态代码。 我在 CloudWatch 中阅读了我的日志和授权 Lambda,每当我发出 HTTP 请求时,它从未被触发。 我正在关注本教程: https://auth0.com/docs/integrations/aws-api-gateway/custom-authorizers/
这是我的授权 lambda 代码:
处理程序:
'use strict';
let jwtManager = require("./jwt_manager");
module.exports.authenticate = (event, context, callback) => {
jwtManager.validate(event, function (error, data) {
if (error) {
if (!error) {
context.fail("Unhandled error");
}
context.fail(error);
}
else {
console.log("SUCCEED");
context.succeed(data);
}
});
};
这是 jwtManager:
"use strict";
require("dotenv").config({ silent: true });
let jwksClient = require("jwks-rsa");
let jwt = require("jsonwebtoken");
module.exports.validate = function(params, callback) {
var token = validateParams(params);
var client = jwksClient({
cache: true,
rateLimit: true,
jwksRequestsPerMinute: 10,
jwksUri: process.env.JWKS_URI
});
var decodedJwt = jwt.decode(token, { complete: true });
var kid = decodedJwt.header.kid;
client.getSigningKey(kid, function(error, data) {
if (error) {
console.log(error);
callback(error);
} else {
var signingKey = data.publicKey || data.rsaPublicKey;
jwt.verify(
token,
signingKey,
{ audience: process.env.AUDIENCE, issuer: process.env.ISSUER },
function(error, decoded) {
if (error) {
console.log("ERROR");
console.log(error);
callback(error);
}
else {
console.log(decoded);
var response = {
principalId: decoded.sub,
policyDocument: getPolicyDocument("Allow", params.methodArn),
context: {
scope: decoded.scope
}
}
console.log(response);
console.log(response.policyDocument);
callback(null, response);
}
}
);
}
});
};
function validateParams(params) {
var token;
if (!params.type || params.type !== "TOKEN") {
throw new Error("Expected 'event.type' parameter to have value TOKEN");
}
var tokenString = params.authorizationToken;
if (!tokenString) {
throw new Error("Expected 'event.authorizationToken' parameter to be set");
}
var match = tokenString.match(/^Bearer (.*)$/);
if (!match || match.length < 2) {
throw new Error(
"Invalid Authorization token - '" +
tokenString +
"' does not match 'Bearer .*'"
);
}
return match[1];
}
function getPolicyDocument(effect, resource) {
var policyDocument = {};
policyDocument.Version = '2012-10-17'; // default version
policyDocument.Statement = [];
var statementOne = {};
statementOne.Action = [ 'execute-api:Invoke', 'lambda:Invoke'] ; // default action
statementOne.Effect = effect;
statementOne.Resource = resource.split('/')[0] + '/*';
policyDocument.Statement[0] = statementOne;
return policyDocument;
}
提前致谢!
当您测试带有自定义授权方的 API 网关但从未触发 auth lambda 函数时,可能是由于令牌标头名称/令牌模式验证中的验证不成功。
我能够重现您的问题。
只有当我在 POSTMAN 中将标题名称从“Authorization”更改为“AuthorizationToken”时才能触发授权方。
我认为这可能是 AWS 门户中的一个新错误,因为我注意到他们不久前更改了 UI 以配置 API Gateway Authorizers。
很奇怪,HTTP 请求必须在名称为“AuthorizationToken”的标头中发送承载令牌。 如果您的 AWS 计划允许您访问他们的技术支持,您应该提醒他们有关此问题的信息。
就我而言,同样的错误(未触发 lambda,授权方失败)是由于我尚未部署 API。 我可能错了,但似乎为了测试授权器,您的 API 必须至少部署一次。
于是,我部署了 API,授权方测试开始工作。
它没有被触发,这可能是由于以下两个原因之一:
对于缓存,您必须等到它过期或使用不同的令牌。 对于测试点,您可以删除缓存。 在后一种情况下,当请求在预期位置不包含令牌时,APIGW 授权方会自动拒绝missing token
的请求。 在这些情况下,您的授权人甚至都不会被使用。
您可以在此示例中看到授权方配置查看identity sources
中的Authorization
header。
如果您没有指定授权 header,则该请求将被自动拒绝。
请求的另一个重要部分是Authorizer Type
。 您的代码正在验证event.type
为TOKEN
。 但是TOKEN
是遗留授权方类型。 当前的最佳做法是使用REQUEST
。 这会将整个请求公开给您的授权者,以便您可以直接正确使用request.headers.Authorization
header。
处理这个问题的最佳方法仍然不是很明显,所以我通常推荐类似apigw 授权程序库的东西,然后将该库为您提供的解析与请求处理相结合。 有关如何处理请求的示例,请参见此处的apigw 授权方。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.