如何对 GCP Cloud Run 上的联合 GraphQL 服务进行身份验证?

Posted

技术标签:

【中文标题】如何对 GCP Cloud Run 上的联合 GraphQL 服务进行身份验证?【英文标题】:How to authenticate against federated GraphQL service on GCP Cloud Run? 【发布时间】:2019-11-12 11:21:55 【问题描述】:

我在 GCP Cloud Run 上有一系列微服务,每个微服务都托管一个联合 Apollo GraphQL 服务。然后我有最后一个容器,它充当其余服务的联合 GraphQL 网关。

当容器上启用公共访问时,这可以正常工作,但我无法让网关服务器针对其他两个服务进行身份验证。

我已经尝试使用 Apollo RemoteGraphQLDataSource 并实现 willSendRequest 方法来设置必要的标头。

我还尝试将云运行调用者角色添加到网关运行的服务角色中。

const servicex = new RemoteGraphQLDataSource(
  url: serviceurl,
  willSendRequest( request, context ) 
    request.http.headers.set(
      "Authorization",
      "Bearer $TOKEN"
    );
  
);


const gateway = new ApolloGateway(
  serviceList: [
    servicex
  ]
);

const  schema, executor  = await gateway.load();

const server = new ApolloServer( schema, executor )

我希望网关服务器能够针对其他微服务进行身份验证。

【问题讨论】:

我刚刚发现 willSendRequest 回调仅在外部服务调用服务时触发,而不是在初始获取联合服务时触发。此处详述未解决问题:github.com/apollographql/apollo-server/issues/2852 【参考方案1】:

Cloud Run 授权需要在您的 authorization: bearer TOKEN HTTP 标头中使用 OAuth 2.0 身份令牌。一个常见的错误是使用访问令牌。

除非您在部署命令中指定了新的服务帐号,否则 Cloud Run 会使用 Compute Engine 默认服务帐号作为其身份。这意味着您需要为 role/run.Invoker 指定服务帐户电子邮件地址。

当您使用 OAuth 授权用户凭据时,您可以收到三个令牌:访问令牌、刷新令牌和身份令牌,具体取决于您在 Scopes 参数中指定的内容。身份令牌是您在 HTTP 授权标头中使用的。

当您使用服务帐号身份授权服务到服务时,请调用 Cloud Run 元数据服务器为您创建令牌。该端点将返回一个身份令牌。在 HTTP 授权标头中使用返回的令牌。

http://metadata/computeMetadata/v1/instance/service-accounts/default/identity?audience=<ususally-the-url-of-the-cloud-run-service-you-are-calling>

返回的令牌是您可以解码的签名 JWT。 header.payload.signature 的典型 base64 编码。有效负载包含服务帐号的电子邮件地址,此电子邮件地址是 Cloud Run 代理用于授权的地址。

【讨论】:

以上是关于如何对 GCP Cloud Run 上的联合 GraphQL 服务进行身份验证?的主要内容,如果未能解决你的问题,请参考以下文章

Terraform GCP:无需用户停机即可更新 Cloud Run 服务

在一个 GCP 项目中来自 Cloud Run 应用的 HTTP 503 错误,但在另一个项目中没有

GCP - 无法在 Cloud Run 中使用 Google Secret Manager (@google-cloud/secret-manager)

GCP 托管的 Cloud Run 的出站 IP 范围是多少?

Cloud Scheduler 调用的 GCP Cloud Run 应用的当前最大超时是多少

我可以为 Terraform for GCP 赋予管理员角色吗? (Cloud Run 域映射示例)