【发布时间】:2022-06-16 15:25:31
【问题描述】:
我在 GCP Cloud Run 中设置了一个由 nginx 前端的 Web 应用程序,效果很好。我正在尝试使用 nginx 将请求代理到 另一个 GCP Cloud Run 服务的某个路由。例如——我希望https://my-cloud-run-frontend.app.run 的请求解析为https://my-cloud-run-frontend.run.app,但是我希望https://my-cloud-run-frontend.run.run/api/* 的请求被代理为https://my-cloud-run-backend.run.app。
两种云运行服务都使用 IAM Auth。
当我在本地 docker 容器中运行我的服务时,代理效果很好。同样,如果我在 Cloud Run 设置中从 frontend 应用程序中删除 IAM 身份验证,一切似乎都正常。
但是,启用 IAM 身份验证后,对 https://my-cloud-run-frontend.run.app 的请求会成功,但对 https://my-cloud-run-frontend.run.app/api/ 的请求会因未经授权而失败(具体来说,错误是从 frontend 云运行应用程序抛出的)。
我已确认身份验证通过使用相同的身份验证令牌并直接向https://my-cloud-run-backend.run.app 和https://my-cloud-run-frontend.run.app 发出请求来工作,并且工作正常。
做一些研究,我发现我可能需要设置一个Host 标头,所以我尝试将标头Host 设置为我的目的地(https://my-cloud-run-backend.run.app url)。这会导致调用 https://my-cloud-run-frontend.run.app/api 返回 400 错误。
我的nginx.conf.template 文件:
server {
access_log /dev/stdout;
listen 8080;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
proxy_set_header Authorization $http_authorization;
proxy_pass_header Authorization;
proxy_pass_request_headers on;
}
location /api/ {
proxy_pass https://my-cloud-run-backend.run.app/;
proxy_set_header Authorization $http_authorization;
proxy_pass_header Authorization;
proxy_set_header Host https://my-cloud-run-backend.run.app;
proxy_pass_request_headers on;
rewrite ^/api(.*)$ $1 break;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
【问题讨论】:
-
它不起作用,因为授权标头也被谷歌前端更改(删除身份令牌签名以防止任何可重用性)。为什么不使用负载均衡器?
-
我不太确定我是否理解——什么时候会发生这种情况?我认为按照我设置 nginx 的方式,应该重新添加该标头,不是吗?负载均衡器不在我批准的技术列表中,并且为此目的感觉有点笨拙/昂贵(将前端代理到后端并转发身份验证)。
-
出于安全原因,授权标头中提供的身份令牌被截断:签名部分已被删除。您可以使用该令牌来了解请求者的身份,但您不能在后续查询中重复使用该令牌。
-
明白,谢谢。我认为是这样,它不会被记录/保存/被盗,对吗?我想我可以传入一个令牌作为参数(比如
myservice.run.app?upstream-token=ey.....),但我认为它的安全含义不太理想?
标签: nginx google-cloud-platform nginx-reverse-proxy google-cloud-run