介绍
当我在玩我的宠物项目Kyiv Station Walk时,我注意到手动删除测试数据很乏味,我需要想出一个管理页面的概念。这需要某种身份验证端点。一些超轻量级的服务,它会检查登录名和密码作为一对超级用户凭据。
无服务器对于这个简单的纳米服务非常有用。这带来了一些成本节省,因为我预计我的低人气服务的管理页面的执行率较低,因此无服务器几乎免费提供给我。另外,我认为这给我带来了一些架构上的好处,因为它允许我将我的核心领域与横切关注点分开。对于我的任务,我决定使用 AWS Lambda。我还决定使用 Go,因为它的简约本质对于 Lambda 实例化很有用。
设置
我们的 lambda 函数将通过 HTTP 从外部调用,因此我们将 HTTP 网关放在它前面,这样它在 AWS 控制台中看起来像下面这样。
项目结构
为了将我们的身份验证逻辑与 FaaS 内部分离,我们的项目将有两个文件:auth.go是身份验证逻辑所在的位置,而main.go是我们的逻辑与 AWS lambda 集成的位置。
main.go的内容如下所示:
要使此代码正常工作,我们需要"github.com/aws/aws-lambda-go/lambda"
package.json 。
为了从外部使用我们的端点,因为我们必须为 API 网关提供特殊格式的响应。出于这个原因,我们也安装了github.com/aws/aws-lambda-go/events
软件包。
让我们突出显示您可能在上面的代码段中注意到的成功响应示例:
错误响应如下所示:
<span style="color:#000000"><span style="background-color:#fbedbb">events.APIGatewayProxyResponse{
StatusCode: status,
Body: http.StatusText(status),
}</span></span>
验证
出于我们的目的,我们将省略持久存储的使用,因为一对凭据就足够了。尽管如此,我们仍然需要使用哈希函数对存储的密码进行哈希处理,这将允许防御者在可接受的时间内验证密码,但攻击者需要大量资源才能从哈希中猜测密码。建议将Argon2用于此类任务。所以要开始,我们需要"github.com/aws/aws-lambda-go/lambda"
包。
<span style="color:#000000"><span style="background-color:#fbedbb">func main() {
lambda.Start(HandleRequest)
}</span></span>
Argon2 已实现,"golang.org/x/crypto/argon2"
因此身份验证非常简单。
请注意,对于错误的登录名和错误的密码,我们如何返回相同的消息以尽可能少地披露信息。这使我们能够防止帐户枚举攻击。
构建它:
<span style="color:#000000"><span style="background-color:#fbedbb">go build -o main main.go
And zipping it
~\Go\Bin\build-lambda-zip.exe -o main.zip main</span></span>
使用视窗
如果您是 Windows 用户,则需要在构建之前设置以下环境变量:
利用环境变量
我们现在可以在代码库中看到硬编码的凭据。这是一种不好的做法,因为它们会自动获取凭据。
您可以在 package.json 的帮助下利用环境变量os
。
<span style="color:#000000"><span style="background-color:#fbedbb">login := os.Getenv(<span style="color:#800080">"</span><span style="color:#800080">LOGIN"</span>)
salt := os.Getenv(<span style="color:#800080">"</span><span style="color:#800080">SALT"</span>)</span></span>
以下是您在 AWS 控制台中设置它们的方法。
智威汤逊一代
一旦服务验证凭据有效,它就会发出一个令牌,允许其持有者充当超级用户。为此,我们将使用JWT,它是访问令牌的事实上的标准格式。
我们需要以下包:
<span style="color:#000000"><span style="background-color:#fbedbb">"github.com/dgrijalva/jwt-go"</span></span>
JWT 生成代码如下所示:
由于拦截此类令牌的对手可能代表超级用户行事,我们不希望此令牌无限有效,因为这将授予对手无限权限。所以我们将令牌过期时间设置为一小时。
测试 API 网关
至此,我们的 API 就可以使用了。这是主服务中的一个简短片段,仅当用户具有足够的权限时才会删除路线。
最小化攻击面
此时,我们的函数存在一些漏洞,因此我们必须在 API 网关上执行一些额外的工作。
端点限制
对于不希望经常调用的授权功能,默认设置太高。让我们改变这一点。