我有一个应用程序在 Docker 容器中运行,并侦听端口 5080 上的 http 流量。托管此(和其他)容器的服务器正在运行 nginx 作为反向代理。 nginx 监听 443 上的 https 流量,当服务器名称匹配时,它会代理到 http://127.0.0.1:5080/。到目前为止一切顺利。
容器中的应用程序使用 Azure 支持的 OpenID 身份验证。我相信我的 Azure 配置正确,包括将回复 URL 设置为
https://example.com/_renarde/security/oidc-success
。
当我尝试登录时,我会被重定向到 login.microsoft.com 并提供我的凭据。一切顺利,因此它尝试将我送回应用程序。但是,我收到此错误:
请求中指定的重定向 URI“http://127.0.0.1:5080/j_oauth_callback”与为应用程序配置的重定向 URI 不匹配
代理地址似乎泄露了。我找到了 nginx 的
proxy_redirect
参考,但这并没有解决问题。
当应用程序向 Azure 发送回复 URL 时,如何让 nginx 使用原始域名?
server {
server_name example.com; # managed by Certbot
location / {
proxy_pass http://127.0.0.1:5080/;
proxy_redirect http://127.0.0.1:5080/ https://example.com/;
proxy_set_header Host $proxy_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
我认为主要问题是您错误地设置了代理
Host
标头。
来自文档:
$proxy_host
proxy_pass 指令中指定的代理服务器的名称和端口;
所以基本上 $proxy_host 将是 127.0.0.1:5080,因此容器中的应用程序将始终认为它以 127.0.0.1:5080 运行。
相反,您可能想要使用
$http_host
,这是原始“Host”请求标头的值。所以基本上你将提供给 nginx 的相同 Host
进一步传递给容器中的应用程序(即 example.com),以便容器中的应用程序知道它。
proxy_set_header Host $http_host;
您的应用程序在重定向到 login.microsoft.com 时,必须提供
redirect_uri
查询字符串参数。我的假设是它尝试指向自身,并从请求的 Host
标头中选择自身的 URL。
至于
proxy_redirect
,如果你的应用程序重定向到自身,它就会触发,例如返回带有标头 Location: http://127.0.0.1:5080/new_location
的响应。但是您的应用程序重定向到login.microsoft.com - 即返回smth。就像 Location: https://login.microsoftonline.com/common/oauth2/v2.0/authorize?redirect_uri=http://127.0.0.1:5080/j_oauth_callback&...
- 在这种情况下它不会被重写。
我相信我的 Azure 配置正确,包括将回复 URL 设置为 https://example.com/_renarde/security/oidc-success。
根据错误消息,回复 URL 的含义似乎与您使用的任何身份验证库作为
redirect_uri
发送到 login.microsoft.com 的 URL 不同。也许它会在身份验证成功后重定向到回复 URL? (如果是这种情况,proxy_redirect
将会很有用)。