在 Google Cloud 托管平台(例如 App Engine)上运行的应用可以使用 Identity-Aware Proxy (IAP) 控制对自身的访问权限,免于管理用户身份验证和会话。IAP 不仅可以控制对应用的访问权限,还可以提供关于经过身份验证的用户的信息,包括其电子邮件地址和以新的 HTTP 标头形式向应用提供的永久性标识符。
目标
要求 App Engine 应用的用户使用 IAP 验证自己的身份。
在应用中访问用户的身份,以显示当前用户的已验证的电子邮件地址。
费用
在本文档中,您将使用 Google Cloud 的以下收费组件:
您可使用价格计算器根据您的预计使用情况来估算费用。
完成本文档中描述的任务后,您可以通过删除所创建的资源来避免继续计费。如需了解详情,请参阅清理。
准备工作
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
- Install the Google Cloud CLI.
-
To initialize the gcloud CLI, run the following command:
gcloud init
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
- Install the Google Cloud CLI.
-
To initialize the gcloud CLI, run the following command:
gcloud init
- 准备开发环境。
设置项目
在终端窗口中,将示例应用代码库克隆到本地机器:
git clone https://github.com/GoogleCloudPlatform/golang-samples.git
转到包含示例代码的目录:
cd golang-samples/getting-started/authenticating-users
背景
本教程使用 IAP 对用户进行身份验证。这只是多种可能方法中的一种。 如需详细了解对用户进行身份验证的各种方法,请参阅身份验证概念部分。
Hello user-email-address
应用
本教程的应用是一个非常小的 Hello World App Engine 应用,具有一个非典型功能:它不显示“Hello World”,而显示“Hello user-email-address
”,其中 user-email-address
是经过身份验证的用户的电子邮件地址。
此功能可以通过检查 IAP 向每个 Web 请求添加的身份验证信息并将其传递给您的应用来实现。到达您的应用的每个 Web 请求中都添加了三个新的请求标头。前两个标头是纯文本字符串,可用于标识用户。第三个标头是包含相同信息的经过加密签名的对象。
X-Goog-Authenticated-User-Email
:用户的电子邮件地址可识别他们。 如果可能,应用应尽量避免存储个人信息。此应用不存储任何数据;它只将其返回给用户。X-Goog-Authenticated-User-Id
:Google 分配的此用户 ID 不会显示用户的相关信息,但能让应用知道登录的用户是回访用户。X-Goog-Iap-Jwt-Assertion
:除了互联网 Web 请求外,您还可以配置 Google Cloud 应用绕过 IAP,接受来自其他云应用的 Web 请求。如果某个应用采用这一配置,则此类请求中有可能包含伪造的标头。 为应对这一问题,您可以使用并验证经过加密签名的标头,确认该信息来自 Google,而不用前面提到的两个纯文本标头。用户的电子邮件地址和永久性用户 ID 都是此签名标头的一部分。
如果您确定应用已配置为只允许互联网 Web 请求对其进行访问,并且没有人可以停用该应用的 IAP 服务,则检索唯一用户 ID 只需要一行代码:
userID := r.Header.Get("X-Goog-Authenticated-User-ID")
不过,灵活的应用应当预见可能出现的问题,包括意外配置或环境问题,因此建议您创建一个可使用并验证加密签名标头的函数。 该标头的签名无法伪造,并且在经过验证后可用于返回身份验证信息。
了解代码
本部分介绍代码的工作原理。如果您想要运行该应用,则可以直接跳至部署应用部分。
go.mod
文件定义了 Go 模块 及其所依赖的模块。app.yaml
文件告知 App Engine 您的代码需要哪种语言环境。应用首先导入软件包并定义
main
函数。main
函数会注册索引处理程序并启动 HTTP 服务器。index
函数会从传入请求中获取 IAP 添加的 JWT 断言标头值,并调用validateAssertion
函数以验证这一加密签名的值。然后,该电子邮件地址会用于极简网页响应。validateAssertion
函数会验证断言是否已正确签名,并返回关联的电子邮件地址和用户 ID。验证 JWT 断言需要知道对断言进行签名的实体(本例中为 Google)的公钥证书,以及断言面向的受众群体。对于 App Engine 应用,该受众群体是包含 Google Cloud 项目标识信息的字符串。
validateAssertion
函数从certs
函数获取这些证书,并从audience
函数获取受众群体字符串。您可以查找 Google Cloud 项目的数字 ID 和名称,并自行将其放入源代码中,但
audience
函数会通过查询每个 App Engine 应用都可使用的标准元数据服务为您做到这一点。由于元数据服务在应用代码的外部,因此该结果保存在返回的全局变量中,而无需在后续调用中查找元数据。App Engine 元数据服务(以及其他 Google Cloud 计算服务的类似元数据服务)看起来像一个网站,可通过标准 Web 查询进行查询。不过,元数据服务实际上并不是外部网站,而是可响应请求并返回关于运行应用的信息的内部功能,因此可以放心地使用
http
请求而非https
请求。元数据服务可用于获取定义 JWT 断言的目标受众群体所需的当前 Google Cloud 标识符。验证数字签名需要签名者的公钥证书。Google 提供一个可返回当前使用的所有公钥证书的网站。系统会缓存这些结果,以防在同一应用实例中再次需要这些结果。
部署应用
现在,您可以部署应用,然后启用 IAP 以要求用户在访问应用之前进行身份验证。
在终端窗口中,转到包含
app.yaml
文件的目录,将应用部署到 App Engine:gcloud app deploy
出现提示时,选择一个附近的区域。
系统询问您是否要继续部署操作时,请输入
Y
。您的应用将在几分钟内在互联网上线。
查看应用:
gcloud app browse
在输出中,复制应用的网址
web-site-url
。在浏览器窗口中粘贴
web-site-url
以打开应用。未显示任何电子邮件,因为您尚未使用 IAP,因此没有任何用户信息发送到应用。
启用 IAP
现在已经有一个 App Engine 实例了,您可以使用 IAP 对其进行保护:
在 Google Cloud 控制台中,转到 Identity-Aware Proxy 页面。
由于这是您第一次为此项目启用身份验证选项,您会看到一条消息,要求您必须先配置 OAuth 同意屏幕,然后才能使用 IAP。
点击配置同意屏幕。
在凭据页面的 OAuth 同意屏幕标签页中,填写以下字段:
如果您的账号属于 Google Workspace 组织,请选择外部,然后点击创建。该应用只能供您明确允许的用户启动。
在应用名称字段中,输入
IAP Example
。在支持电子邮件字段中,输入您的电子邮件地址。
在已获授权的网域字段中,输入应用网址的主机名部分,例如
iap-example-999999.uc.r.appspot.com
。在字段中输入主机名后按Enter
键。在应用首页链接字段中,输入应用的网址,例如
https://iap-example-999999.uc.r.appspot.com/
。在应用隐私权政策链接字段中,使用与首页链接相同的网址以进行测试。
点击保存。当系统提示您创建凭据时,您可以关闭该窗口。
在 Google Cloud 控制台中,转到 Identity-Aware Proxy 页面。
如需刷新页面,请点击刷新 refresh。该页面会显示您可以保护的资源列表。
在 IAP 列中,点击应用,对其启用 IAP。
在浏览器中,再次转到
web-site-url
。您无需使用相应页面,可通过登录屏幕自行验证身份。 您登录时,由于 IAP 中没有允许访问应用的用户列表,因此您无法访问。
将已获授权的用户添加到应用
在 Google Cloud 控制台中,转到 Identity-Aware Proxy 页面。
选中 App Engine 应用的复选框,然后点击添加主账号。
输入
allAuthenticatedUsers
,然后选择 Cloud IAP/IAP-Secured Web App User 角色。点击保存。
现在,Google 可验证的任何用户都可以访问该应用。您还可以根据情况通过仅添加一个或多个用户或组作为主账号,以便进一步限制访问权限:
任何 Gmail 或 Google Workspace 电子邮件地址
Google 群组电子邮件地址
Google Workspace 域名
访问应用
在浏览器中,转到
web-site-url
。如需刷新页面,请点击刷新 refresh。
在登录屏幕上,使用您的 Google 凭据登录。
该页面会显示一个包含您的电子邮件地址的“Hello
user-email-address
”网页。如果您看到的页面未发生变化,而现在您已经启用了 IAP,这可能是浏览器存在某个问题,不能完全更新新请求。请关闭所有浏览器窗口,再重新打开,然后重试。
身份验证概念
应用可以通过多种方式对其用户进行身份验证,并仅允许已获授权的用户进行访问。以下各部分列出了常见的身份验证方法,这些方法按应用工作量的多少降序排列。
选项 | 优点 | 缺点 |
---|---|---|
应用身份验证 |
|
|
OAuth2 |
|
|
IAP |
|
|
应用管理的身份验证
使用此方法,应用可单独管理用户身份验证的各个方面。应用必须维护自己的用户凭据数据库并管理用户会话,并且需要提供各类功能,以便管理用户账号和密码、检查用户凭据,以及在每次经过验证的登录后发布、检查和更新用户会话。下图说明了应用管理的身份验证方法。
如图所示,用户登录后,应用会创建和维护用户会话的相关信息。当用户向应用发出请求时,请求必须包含相应会话信息,应用负责验证此类信息。
这种方法的主要优势在于它是在应用的控制下独立完成的。应用甚至无需联网。主要缺点是应用现在要负责提供所有账号管理功能,并保护所有敏感凭据数据。
使用 OAuth2 进行外部身份验证
如果不希望在应用内处理所有流程,不妨选择使用 Google 等外部身份服务来处理所有用户账号的信息和功能,并负责保护敏感凭据。当用户尝试登录应用时,请求会被重定向至身份服务,该服务对用户进行身份验证,然后将请求重定向回应用,同时提供必要的身份验证信息。如需了解详情,请参阅针对网络服务器应用使用 OAuth 2.0。
下图说明了使用 OAuth2 方法进行外部身份验证的过程。
用户发送请求以访问应用时,图中的流程即开始。应用并没有直接响应,而是将用户的浏览器重定向至 Google 的身份平台,此平台显示可登录 Google 的页面。成功登录后,用户的浏览器将定向至应用。此请求包含当前经过身份验证的用户的信息,供应用进行查询,然后应用会对客户做出响应。
此方法对应用有许多优势。它可以由外部服务承担所有的账号管理功能和风险,从而提高登录和账号安全性,而无需更改应用。不过,如上图所示,应用必须能够访问互联网才能使用此方法。应用还负责在用户通过身份验证后管理会话。
Identity-Aware Proxy
本教程介绍的第三种方法是使用 IAP 处理对应用进行任何更改的所有身份验证和会话管理。IAP 会拦截指向应用的所有 Web 请求,阻止任何尚未经过身份验证的请求,并将其它请求在添加用户身份数据后传给应用。
其请求处理流程如下图所示。
IAP 拦截来自用户的请求,并阻止未经身份验证的请求。经过身份验证的请求会传递到应用,前提是经过身份验证的用户在允许用户列表中。通过 IAP 传递的请求中添加了标头,用于标识发出请求的用户。
该应用不再需要处理任何用户账号或会话信息。任何需要了解用户唯一标识符的操作都可以直接从每个传入的 Web 请求中获取。但是,这种方法只能用于支持 IAP 的计算服务,例如 App Engine 和负载均衡器。您无法在本地开发机器上使用 IAP。
清除数据
为避免因本教程中使用的资源导致您的 Google Cloud 账号产生费用,请删除包含这些资源的项目,或者保留项目但删除各个资源。
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.