1

假设我有一个托管在谷歌云上的应用程序:前端和后端。要求是该应用程序只能由特定组内的用户或具有特定角色等的用户在特定的谷歌组织(包含该应用程序的项目所属)内使用。

我想像这样实现它:

1) 前端将要求用户使用谷歌作为第 3 方身份验证器使用他的谷歌账户(我希望它与谷歌云组织绑定)登录。由于该应用程序是使用 node/javascript 构建的,因此可以使用某些npm包(例如passport. 在用户从浏览器登录并发生特定重定向后,Google 应向后端提供有关用户的信息,包括唯一标识符。

2) 后端(在应用引擎、计算引擎等上运行都无关紧要)应该访问一个谷歌云特定的 API,该 API 应该识别用户以及用户是属于一个组还是属于组织,基本上任何有助于。假设该机器将拥有一个服务帐户,该服务帐户具有访问所述 API 并确定用户是否正常的所有必要角色。

3)如果用户正常,那么将为用户在后端创建一个会话,只要该会话存在,后端就会知道请求的身份,所以一切都应该没问题。

我遇到的问题在于第 2 步:查看整个 Google IAM、API、文档视频等。我找不到任何方法来 a)根据唯一 ID 识别用户,b)验证是否用户是组的一部分(通过单独的成员资格资源或其他方式),或者如果它具有关联的特定角色,这相当于我的用例。

任何想法,如果:

1)我的方法是有道理的,这甚至可能吗?

2)如果是这样,那么我应该使用哪些资源或方法来实现它?

3)如果不是那么什么方法适合我的用例?

4

1 回答 1

2

关键问题是谁将成为您的身份提供者?

下一个关键问题是如何将用户的身份从身份提供者映射到您自己的用户/权限数据库。

您要决定的下一个关键问题是使用哪种类型的 OAuth 2.0。隐式 OAuth 或 3-legged OAuth。隐式 OAuth 在浏览器中完成,仅涉及客户端 ID。3-legged OAuth 涉及用于接收令牌的 Web 服务器,被认为更安全。

1) 前端将要求用户使用谷歌作为第 3 方身份验证器使用他的谷歌账户(我希望它与谷歌云组织绑定)登录。由于该应用程序是使用 node/javascript 构建的,因此可以使用一些 npm 包(例如护照)轻松完成。在用户从浏览器登录并发生特定重定向后,Google 应向后端提供有关用户的信息,包括唯一标识符。

您可以使用任何身份提供商(Google、Facebook、Auth0、Okta 等)。(注意:请参阅我对 Google IAM 的进一步评论)。在浏览器中实现 OAuth 非常简单,您真的不需要库。但是,如果您想使用库,则有很多可供选择。但是,选择一个原生 JavaScript 而不是节点包的库。节点包往往会创建用户必须下载的巨大文件。

OAuth 流程完成后,您将拥有两个令牌。访问令牌和 ID 令牌。ID 令牌是您的 JavaScript 前端将包含在请求中的内容。我将在此答案中忽略访问令牌,但如果在身份验证阶段正确设置,它可用于直接访问 GCP 服务,例如 Google 存储。对于这个答案,我假设您想要用户的身份。

2) 后端(在应用引擎、计算引擎等上运行都无关紧要)应该访问一个谷歌云特定的 API,该 API 应该识别用户以及用户是属于一个组还是属于组织,基本上任何有助于。假设该机器将拥有一个服务帐户,该服务帐户具有访问所述 API 并确定用户是否正常的所有必要角色。

在与您的服务通信时,客户端浏览器将在 HTTP 标头、隐藏的表单字段、会话状态等中包含 ID 令牌。要验证 ID 令牌,您调用特定于身份提供者的端点。对于 Google,端点是:https://www.googleapis.com/oauth2/v3/tokeninfo,对于 Auth0,它是:https://<replace_with_your_account_name>.auth0.com/userinfo。这些端点都验证 ID 令牌的完整性。ID 令牌包含用户授权您查看的用户详细信息。ID Token 是一个 JWT,在为 Google 解码时如下所示:

iss: https://accounts.google.com
azp: <removed_for_security>.apps.googleusercontent.com
aud: <removed_for_security>.apps.googleusercontent.com
sub: <removed_for_security>
hd: example.com
email: username@example.com.com
email_verified: true
at_hash: 63I_abcdefabcdefbi5NSw
nonce: e8TP-uLoEoeXpbk5
name: User Name
picture: https://lh3.googleusercontent.com/-9PtQwhKbOPc/AAAAAAAAAAI/AAAAAAAAAAA/<removed_for_security>/s96-c/photo.jpg
given_name: User
family_name: Name
locale: en
iat: 1548357229
exp: 1548360829
jti: <removed_for_security>

您的后端将负责将用户的身份映射到您想要的任何权限。您可以使用数据库等来存储此信息。如果用户也是 Google IAM 用户,您可以根据存储在 Google IAM 中的 IAM 权限生成短期凭证。但是,我只建议您只有少数用户的情况下使用此方法。对于成百上千的用户,不要使用 Google IAM,而是通过您的身份提供者通过自定义声明或在您自己的自定义数据库中进行管理。

3)如果用户正常,那么将为用户在后端创建一个会话,只要该会话存在,后端就会知道请求的身份,所以一切都应该没问题。

我不确定你想在这里说什么。对于 Google Cloud,您的后端将使用其服务帐户代表客户端发出请求,或者后端将创建一个短期访问令牌来授予访问权限。

1)我的方法是有道理的,这甚至可能吗?

您的方法非常接近应该如何完成。有一些细节你还不明白,我希望我的回答能给你指明正确的方向去研究更多。

2)如果是这样,那么我应该使用哪些资源或方法来实现它?

  • 确定您将实施的 OAuth 类型(隐式或 3-legged)。
  • 决定身份提供者。谷歌、Facebook、Auth0 等。
  • 决定您将在浏览器中嵌入的代码类型(简单的 JavaScript 或库)
  • 决定如何通过 HTTP 标头、隐藏的表单字段等传递令牌。
  • 决定您将如何授权请求。您自己的服务帐户或为每个用户创建的短期访问令牌。
  • 决定如何将 ID 令牌身份转换为您的权限集。

3)如果不是那么什么方法适合我的用例?

您的方法很好,是我们在现实世界中所做的典型做法。

于 2019-01-24T19:34:23.870 回答