我希望为AWS Lambda / zappa使用一些“无服务器api服务器”,它使用自定义API网关授权程序进行用户身份验证。在无服务器的AWS lambda服务中,使用自定义授权器而不是直接在代码控制器中检查已发布的JWT令牌是否具有相当大的安全性或成本优势?对我来说,检查代码可能更方便。
UPDATE 我去了pre请求钩子,但是有头级别的授权器,它更容易用于CORS,但zappa不支持它我相信。也可以通过swagger上传为Options设置模拟API,如果成功则会更新。
答案 0 :(得分:6)
我认为没有严格的安全或成本效益。好处是它是一个单一的地方,一个代码,处理您的授权。它可以防止您在API后面部署的每个Lambda函数中复制该授权代码。它允许您更新单个函数以对授权逻辑进行任何更改。
从它为您的授权逻辑提供single source of truth的角度来看,它允许您实现separation of concerns,可以说它可以增强您的应用程序的安全性。
话虽这么说,如果你的整个API都包含一个Lambda函数,那么这个好处有点可疑。我认为当您的API具有许多Lambda函数或者您的API网关位于传统HTTP服务器之前时,API网关自定义授权程序真正变得有用。
答案 1 :(得分:1)
@Mark B提出了很好的观点我当然不会对他的回答提出异议。不过,我还是想为这次谈话做出贡献。
为您量身定制的答案可能取决于JWT的来源,以及如何获取,使用和刷新它们。在这些场景中使用自定义授权器可能有意义:
使用案例1
如果您希望在几种不同版本的授权后面保护单个Lambda,则自定义授权器非常有用。例如,您可以创建三个不同的API网关端点,每个端点都调用相同的Lambda,但使用不同的授权程序。这与马克关于DRY福利的观点有关。
使用案例2
自定义授权程序使您能够在授权程序代码中内联构建IAM权限。您可以构建任何您喜欢的任意权限集,而不是将预先存在的IAM角色分配给调用者。请注意,如果您以某种方式使用(不受信任的)用户输入来分配IAM权限,这很容易成为讨厌的攻击媒介。
使用案例3
Lambdas非常适合隐藏秘密。例如,您有一个前端JS应用程序,您需要参与需要客户端ID和客户端密钥的OAuth 2.0流程。或者您需要调用需要某种API密钥的端点。 显然,您无法将这些秘密暴露给浏览器。
这些值可以是Lambda函数特有的encrypted and stored in environment variables。虽然您可以使用后端lambda采用这种方法,但使用授权器会产生以下好处:
我希望能够尽可能严格地限制这些秘密的范围。通过使用授权人,我的应用程序可以保持幸福地不知道这些秘密。这与马克关于分离关注点的观点有关。
IAM和最低权限
我更喜欢我的后端代码永远不会被未经授权的各方调用。出于这个原因,我在几乎所有我创建的API网关资源上都使用了某种类型的授权程序。我使用了自定义授权程序,但它们是我最后的手段。我大部分时间依靠IAM授权,使用Cognito交换令牌以获取临时IAM凭证。
如果您在后端lambda中执行授权,而不是在授权程序中执行授权,则在定义后端lambda周围的IAM控制时,您不能具有限制性。这违反了principle of least privilege。这不仅仅是代码组织和应用程序架构的问题;这是一个合法的安全问题。你基本上暴露了比你更多的攻击面。
此外,当你的后端增长时,IAM的真正力量会闪耀。您的后端lambda可能需要写入S3,调用其他Lambdas,发布到SNS或SQS,与RDS或DynamoDB交互等。我建议“最佳实践”规定所有这些访问都受严格的IAM控制政策。根据我的经验,使用API网关授权程序(任何类型,不一定是自定义)来分配角色是实现此目的最直接的方法。
答案 2 :(得分:0)
问题的费用部分。 授权者将为另外一个lambda呼叫和新的CPU时间分别收取100ms的最低费用。 如果后端有很多短的lambda,这可能是一笔不小的费用,可能会使每一个的lambda费用翻倍。