使用 Go 和 AWS Lambda 构建 Auth Endpoint

介绍

当我在玩我的宠物项目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"包。

JavaScript
<span style="color:#000000"><span style="background-color:#fbedbb">func main() {
    lambda.Start(HandleRequest)
}</span></span>

Argon2 已实现,"golang.org/x/crypto/argon2"因此身份验证非常简单。

JavaScript

请注意,对于错误的登录名和错误的密码,我们如何返回相同的消息以尽可能少地披露信息。这使我们能够防止帐户枚举攻击。

构建它:

<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

JavaScript
<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 生成代码如下所示:

JavaScript

由于拦截此类令牌的对手可能代表超级用户行事,我们不希望此令牌无限有效,因为这将授予对手无限权限。所以我们将令牌过期时间设置为一小时。

测试 API 网关

至此,我们的 API 就可以使用了。这是主服务中的一个简短片段,仅当用户具有足够的权限时才会删除路线。

F#
收缩▲   

最小化攻击面

此时,我们的函数存在一些漏洞,因此我们必须在 API 网关上执行一些额外的工作。

端点限制

对于不希望经常调用的授权功能,默认设置太高。让我们改变这一点。

猜你喜欢

转载自blog.csdn.net/wouderw/article/details/127711141#comments_24016279