使用 IAP 服务到 App Engine 上的服务请求

Service to service requests on App Engine with IAP

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

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

问题:我还为 App Engine 打开了 Identity-Aware 代理。当我尝试从我的 NextJS 服务向我的 API(server-side,通过 getServerSideProps)发出 GET 请求时,它会再次触发 IAP sign-in 页面,而不是击中我的 API。我已经尝试了一些想法来解决这个问题:

  1. 转发 API 请求中的所有 cookie
  2. 如前所述设置 X-Requested-With header here
  3. 将 IAP-secured Web 应用程序用户权限授予我的 App Engine 默认服务帐户

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

您需要执行服务到服务呼叫。那不是那么简单,您还没有真正的例子。无论如何,我测试了(在 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 运行(和 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 页面(安全 -> 身份识别代理),单击 App Engine 前面的复选框,然后转到页面右侧的权限面板


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

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