【问题标题】:Service to service requests on App Engine with IAP使用 IAP 在 App Engine 上提供服务到服务请求
【发布时间】:2021-05-27 04:04:31
【问题描述】:

我正在使用 Google App Engine 来托管几个服务(NextJS SSR 服务和基于 Express 构建的后端 API)。我已经设置了我的dispatch.yaml 文件以将/api/* 请求路由到我的API 服务,所有其他请求都被路由到default (NextJS) 服务。

dispatch:
  - url: '*/api/*'
    service: api

问题:我还为 App Engine 开启了 Identity-Aware Proxy。当我尝试从我的 NextJS 服务向我的 API(服务器端,通过 getServerSideProps)发出 GET 请求时,它会再次触发 IAP 登录页面,而不是点击我的 API。我尝试了一些想法来解决这个问题:

  1. 在 API 请求中转发所有 cookie
  2. 设置X-Requested-With 标头,如here 所述
  3. 向我的 App Engine 默认服务帐户授予受 IAP 保护的 Web 应用用户权限

但似乎没有任何效果。我已经确认关闭 App Engine 的 IAP 可以让一切按预期运行。从前端对 API 的任何请求也可以按预期工作。是否有我缺少的解决方案或解决方法?

【问题讨论】:

  • 如何在代码中执行您的请求?您是否在 Authorization 标头中添加了承载 id 令牌?
  • @guillaumeblaquiere 不,我使用 Axios 发出 GET 请求并在 cookie 标头中从前端传递 cookie
  • 好的,您在 IAP 后面有一个前端服务调用 IAP 后面的后端服务?还是后端服务调用另一个后端服务?
  • 如何关闭后端服务上的 IAP 并添加不记名令牌验证?当您在内部进行调用时,您会包含该令牌。公共用户将没有该令牌,这意味着他们对后端服务的调用将失败。注意:根据文档 - cloud.google.com/iap/docs/managing-access - 您应该能够单独打开/关闭后端服务与其他 Web 服务的 IAP
  • @guillaumeblaquiere 这是一个调用另一个后端服务的后端服务。两者都通过 IAP 背后的 App Engine 部署

标签: google-app-engine google-cloud-platform next.js google-iap identity-aware-proxy


【解决方案1】:

您需要执行服务到服务调用。这不是那么简单,你没有真正的例子。无论如何,我测试了(在 Go 中)并且它有效。

首先,基于Cloud Run Service to Service 文档页面进行开发。

您将在 NodeJS 中使用这段代码抱歉,我不是 NodeJS 开发人员,更不是 NexJS 开发人员,您必须适应

// Make sure to `npm install --save request-promise` or add the dependency to your package.json
const request = require('request-promise');

const receivingServiceURL = ...

// Set up metadata server request
// See https://cloud.google.com/compute/docs/instances/verifying-instance-identity#request_signature
const metadataServerTokenURL = 'http://metadata/computeMetadata/v1/instance/service-accounts/default/identity?audience=';
const tokenRequestOptions = {
    uri: metadataServerTokenURL + receivingServiceURL,
    headers: {
        'Metadata-Flavor': 'Google'
    }
};

// Fetch the token, then provide the token in the request to the receiving service
request(tokenRequestOptions)
  .then((token) => {
    return request(receivingServiceURL).auth(null, null, true, token)
  })
  .then((response) => {
    res.status(200).send(response);
  })
  .catch((error) => {
    res.status(400).send(error);
  });    

此示例行不通,因为您需要正确的受众。这里,变量是receivingServiceURL。这对于 Cloud Run(和 Cloud Functions)是正确的,但对于 IAP 后面的 App Engine 是不正确的。您需要使用名为 IAP-App-Engine-app 的 OAuth2 凭据的客户端 ID

好的,很难理解我在说什么。所以,去控制台,API & Services -> Creentials。从那里,您有一个 OAuth2 客户端 ID 部分。复制IAP-App-Engine-app行的Client ID列,像这样

最后一点,请确保您的 App Engine 默认服务帐户有权访问 IAP。并将其添加为IAP-secured Web App User。服务帐号的格式为<PROJECT_ID>@appspot.gserviceaccount.com

也不是很清楚。因此,进入 IAP 页面(Security -> Identity Aware Proxy),点击 App Engine 前面的复选框,然后进入页面右侧,在权限面板中


同时,我可以解释如何在特定服务上停用 IAP(由 NoCommandLine 提议)。 只是一句话:当您遇到问题时停用安全性绝不是一个好主意!

从技术上讲,您不能在服务上停用 IAP。但是您可以在特定服务上将allUsers 授予IAP-secured Web App User(而不是单击App Engine 的复选框,而是单击特定服务的复选框)。就像这样,即使使用 IAP,您也授权所有用户访问您的服务。 实际上是没有检查的激活。

【讨论】:

  • 建议是关闭 IAP 并替换为 bearer token verification,这意味着仍然应该有某种安全性。这可能不是最好的安全方法,但我们同意关闭安全绝对不是最好的解决方案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-09
  • 2013-05-22
  • 1970-01-01
相关资源
最近更新 更多