如何使用 google 服务帐户和 oauth 限制对我的 google 云函数的调用?
How do I limit invocations to my google cloudfunction using a google service account and oauth?
我有一个云函数,我想从目前在 Heroku 上 运行 的 rails 应用调用。我为 rails 应用程序设置了一个服务帐户,并且 could 函数由 HTTP 请求部署和触发。我想将云功能的调用限制在 rails 应用程序中,并计划在 google.
之后的 this documentation 之后使用服务器到服务器的 2-legged OAuth 2.0 ]
不过,当我设置服务帐户时,我需要提供一个范围。根据 available scopes 的列表,唯一引用 Cloud Functions 的范围允许管理云功能,而我希望范围仅涵盖调用。
文档中使用的语言是指用于定义对 Google API 的访问的范围。
- 从这个意义上说,我的云函数是否符合 google API 的条件?
- 否则,由于范围是 URL,我可以只提供我的云函数的 URL 作为范围吗?
关于 this topic 的 Cloud Functions 文档涵盖了几个用例:
Securing developer access so that only specific users can invoke the
function during testing.
Securing function-to-function access so that only authorized functions
can invoke your function.
Securing end-user access to an application from mobile or web clients.
您的用例是第三个,最终用户身份验证是通过 Google Sign-In and Firebase Authentication 集成的,但这对于限制 HTTP 调用仅允许您的 Heroku 应用程序没有用。
此时应通过检查您的 Cloud Functions 代码中的请求是否来自 Heroku 应用程序来管理解决方法,并拒绝那些不是的请求。
是的,我设法从几个不同的 Google 文档页面拼凑了这个过程,即
- https://cloud.google.com/iap/docs/authentication-howto#authenticating_from_a_service_account
- 错误地指示您 self-sign 您的 JWT,这显然行不通,因为这样任何人都可以签署自己的 JWT 并访问您的云功能
- https://cloud.google.com/functions/docs/securing/authenticating#service-to-function
- 此示例不会告诉您在初始 JWT 声明中设置哪些受众
- https://developers.google.com/identity/protocols/OAuth2ServiceAccount#authorizingrequests
- 错误描述了 JWT 声明内容和签名过程
- 直接使用服务帐户签名的 JWT 作为承载令牌的 alternate method 不适用于调用云函数,我猜是因为它们不是 google API
这是对我有用的
使用以下数据编组 JWT。主要技巧是将 aud
设置为 OAuth 端点,将 sub
设置为服务帐户的电子邮件(即使没有用户可模拟),并将 target_audience
设置为 Cloud Function 的 URL(根据文档 #1),但遵循文档 #3 中的一般流程。
{
"aud": "https://www.googleapis.com/oauth2/v4/token",
"sub": "<your service account's email style identifier>",
"iss": "<your service account's email style identifier>",
"target_audience": "<the URL of the cloud function you're trying to call>",
"exp": <unix epoch timestamp + 3600 as an integer>,
"iat": <unix epoch timestamp as an integer>
}
Base64 编码声明。根据 doc #3 中的通用说明,Base64 编码声明 header 集 ({"alg":"RS256","typ":"JWT"}
) 并将结果与句点 header.claim
组合。你应该得到这样的东西:eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3NjEzMjY3OTgwNjkt...
。与文档 #3 相反,您不需要 header 中的 kid
。
使用服务帐户私钥与您喜欢的 JWT 库签署 JWT
通过 POST 使用 [=19] 调用 https://www.googleapis.com/oauth2/v4/token
,将您的服务帐户签名的 JWT 交换为来自 Google 的 OAuth 系统的访问令牌=] 和以下两个字段形成编码的数据:
grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer
assertion: <signed JWT base64 encoded string, YES you use it twice>
如果一切顺利,您应该会收到包含密钥 id_token
的 JSON 响应,您可以在调用 CloudFunction 时在 Authorization: Bearer <id_token>
中使用它
我有一个云函数,我想从目前在 Heroku 上 运行 的 rails 应用调用。我为 rails 应用程序设置了一个服务帐户,并且 could 函数由 HTTP 请求部署和触发。我想将云功能的调用限制在 rails 应用程序中,并计划在 google.
之后的 this documentation 之后使用服务器到服务器的 2-legged OAuth 2.0 ]不过,当我设置服务帐户时,我需要提供一个范围。根据 available scopes 的列表,唯一引用 Cloud Functions 的范围允许管理云功能,而我希望范围仅涵盖调用。
文档中使用的语言是指用于定义对 Google API 的访问的范围。
- 从这个意义上说,我的云函数是否符合 google API 的条件?
- 否则,由于范围是 URL,我可以只提供我的云函数的 URL 作为范围吗?
关于 this topic 的 Cloud Functions 文档涵盖了几个用例:
Securing developer access so that only specific users can invoke the function during testing.
Securing function-to-function access so that only authorized functions can invoke your function.
Securing end-user access to an application from mobile or web clients.
您的用例是第三个,最终用户身份验证是通过 Google Sign-In and Firebase Authentication 集成的,但这对于限制 HTTP 调用仅允许您的 Heroku 应用程序没有用。
此时应通过检查您的 Cloud Functions 代码中的请求是否来自 Heroku 应用程序来管理解决方法,并拒绝那些不是的请求。
是的,我设法从几个不同的 Google 文档页面拼凑了这个过程,即
- https://cloud.google.com/iap/docs/authentication-howto#authenticating_from_a_service_account
- 错误地指示您 self-sign 您的 JWT,这显然行不通,因为这样任何人都可以签署自己的 JWT 并访问您的云功能
- https://cloud.google.com/functions/docs/securing/authenticating#service-to-function
- 此示例不会告诉您在初始 JWT 声明中设置哪些受众
- https://developers.google.com/identity/protocols/OAuth2ServiceAccount#authorizingrequests
- 错误描述了 JWT 声明内容和签名过程
- 直接使用服务帐户签名的 JWT 作为承载令牌的 alternate method 不适用于调用云函数,我猜是因为它们不是 google API
这是对我有用的
使用以下数据编组 JWT。主要技巧是将
aud
设置为 OAuth 端点,将sub
设置为服务帐户的电子邮件(即使没有用户可模拟),并将target_audience
设置为 Cloud Function 的 URL(根据文档 #1),但遵循文档 #3 中的一般流程。{ "aud": "https://www.googleapis.com/oauth2/v4/token", "sub": "<your service account's email style identifier>", "iss": "<your service account's email style identifier>", "target_audience": "<the URL of the cloud function you're trying to call>", "exp": <unix epoch timestamp + 3600 as an integer>, "iat": <unix epoch timestamp as an integer> }
Base64 编码声明。根据 doc #3 中的通用说明,Base64 编码声明 header 集 (
{"alg":"RS256","typ":"JWT"}
) 并将结果与句点header.claim
组合。你应该得到这样的东西:eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3NjEzMjY3OTgwNjkt...
。与文档 #3 相反,您不需要 header 中的kid
。使用服务帐户私钥与您喜欢的 JWT 库签署 JWT
通过 POST 使用 [=19] 调用
https://www.googleapis.com/oauth2/v4/token
,将您的服务帐户签名的 JWT 交换为来自 Google 的 OAuth 系统的访问令牌=] 和以下两个字段形成编码的数据:grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer
assertion: <signed JWT base64 encoded string, YES you use it twice>
如果一切顺利,您应该会收到包含密钥
id_token
的 JSON 响应,您可以在调用 CloudFunction 时在Authorization: Bearer <id_token>
中使用它