python - 如何使用内置身份验证机制保护我的 Azure WebApp
问题描述
我用 Python 创建了一个 Flask-Webservice,它在 docker 容器中独立运行。然后,我将 docker 映像上传到 Azure 容器注册表。从那里,我可以在 Azure 门户中单击几下创建一个运行此容器的 WebService(用于容器)。到目前为止,一切都很好。它的行为就像我想要的那样。
但我当然不希望任何人访问该服务。所以我需要某种身份验证。幸运的是(或者我认为)有一个内置的身份验证机制(我认为它基于 OAuth ......我对安全问题并不那么精通)。它的文档对实际发生的事情有点稀疏,并且还专注于 C# 中的解决方案。
我首先按照此处所述使用 Google 创建了一个项目,然后使用 Client-Id 和 Secret 配置了 WebApp-Authentication。我当然也给了 Google 一个 java 脚本源和回调 URL。
当我现在注销我的 Google 帐户并尝试在浏览器中对我的 Web 服务发出 GET 请求(GET 应该只返回一个“hello world”-字符串)时,我会看到一个登录屏幕……正如我所料。
当我现在再次登录 Google 时,我被重定向到浏览器中的回调 URL,参数中包含某种信息。
也许是一个令牌?它看起来像这样:
这里出了点问题,因为出现了错误。
发生错误。
抱歉,您要查找的页面目前不可用。请稍后再试。
如果您是此资源的系统管理员,则应查看错误日志以获取详细信息。
忠实于你的,nginx。
就我现在而言,nginx 是一个托管我的代码的服务器软件。我可以想象它也应该处理身份验证过程。当身份验证关闭时,它显然允许所有请求通过我的代码,但会阻止未经身份验证的访问并重定向到谷歌登录。然后,Google 会检查您的帐户是否已获得该应用程序的授权,并将您重定向到带有访问令牌的回调。然后这会返回一个 cookie,它应该允许我的浏览器访问该应用程序。(我只是在这里复制文档)。
所以我的问题是:出了什么问题。我的浏览器不接受 cookie。在 WebApp 中配置 Google+ 或身份验证时我有什么问题吗?我是否必须使用某个开发堆栈才能使用身份验证。我使用的任何技术(Python、Flask ...)都不支持它吗?
编辑
@米克尼克:
在 Microsoft 的身份验证/授权文档中,它说
身份验证和授权模块与您的应用程序代码在同一沙箱中运行。启用后,每个传入的 HTTP 请求都会通过它,然后由您的应用程序代码处理。
...
该模块与您的应用程序代码分开运行,并使用应用程序设置进行配置。无需 SDK、特定语言或更改您的应用程序代码。
因此,虽然您可能是正确的,回调重定向中的信息是授权授予/代码,并且在此之后现在应该使用此代码从 Google 获取访问令牌,但我不太明白这将如何在我的情况。
据我所见,Microsofts WebApp for Container-Resource on Azure 应该负责自动获取令牌并将其作为对回调请求的响应的一部分返回。文档说明了 4 个步骤:
- 登录用户:将客户端重定向到 /.auth/login/。
- 身份验证后:提供商将客户端重定向到 /.auth/login//callback。
- 建立经过身份验证的会话:应用服务将经过身份验证的 cookie 添加到响应中。
- 提供经过身份验证的内容:客户端在后续请求中包含身份验证 cookie(由浏览器自动处理)。
在我看来,第 2 步失败了,这正是您所写的:授权授予将由服务器用于获取访问令牌,但不是。
但我也没有任何控制权。也许有人可以通过在其他一些事情上纠正我来澄清事情:
首先,我不太清楚我的问题的哪些部分代表了 OAuth 方案中的哪个角色。
- 我认为我是Owner,通过将用户添加到 Google+-Project 的列表中,我授权他们使用我的服务。
- 谷歌显然是授权服务器
- 我的 WebService(或者更好的是我的 WebApp for Containers)是资源服务器
- 最后一个执行请求的应用程序或邮递员是客户端
在 OAuth 的描述中,我读到有问题的步骤归结为:资源服务器从授权服务器获取访问令牌并将其传递给客户端。通过使用回调 url 调用 Azures WebApps 资源会提示(并启用)这样做。我在这方面的某个地方吗?
唉,我同意我不太了解整个协议。但我发现网上的大多数描述都没有多大帮助,因为它们不是特定于 Azure 的。如果有人知道一个好的解释,一般的或特定于 Azure 的,请发表评论。
解决方案
我找到了一种让它发挥作用的方法,并尽我所能解释出了什么问题。如果我错了或使用了错误的词,请纠正我。
我怀疑问题不在于我不了解 OAuth(或至少 Azure 如何管理它),而是 Azure WebApp 服务的内部工作原理(加上我的一些糟糕的编程)。Azure 运行自己的服务器,不使用烧瓶的内置服务器。实际的问题是我的烧瓶程序没有实现 WSGI 接口。据我所知,这是 python 脚本与任何服务器交互的另一个标准。因此,虽然来自服务器的基本调用(我认为 Azure 使用 nginx)是可能的,但更复杂的调用,比如重定向到回调 url 去了 dev/null。
我按照本教程构建了一个新应用程序,然后按照身份验证/授权教程进行保护,一切正常。本教程中的代码实现了 WSGI,并且可能更符合 Azure 的预期。我的 docker 解决方案太简单了。
我的结论:阅读这个 WSGI 标准,flask 总是警告我,我没有在任何代码中倾听和实现它,而不仅仅是在开发中摆弄。
推荐阅读
- python - 从 URL 解压 rar 文件
- php - 如何在 Symfony 5 的其他目录中自动注册“控制器作为服务”
- c# - c#互操作中的Excel多列过滤器
- java - 具有可选空值和不区分大小写的 Spring Query
- python - 训练模型后无法提取单个预测
- python - 我可以检查一个列表是否包含另一个列表中的任何项目吗?
- dart - 如何全局捕获未处理的 Future 错误?
- node.js - Strapi 使用 SendGrid“内部错误”发送电子邮件
- python - 命令中的 python -m 前缀如何工作?
- azure - 从 LogicApp 中的 json 获取值