如何解决使用 auth_request_module 反向代理应用程序的 Nginx 引发 CORS 错误
我正在开发一个 nginx 服务器,仅当用户通过身份验证时,它才能用作本地 web 应用程序的反向代理。
这是我在 myconfiguration.conf
内的 nginx etc/nginx/sites-enabled/
飞行:
# Proxy Server to back-end site
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name internal.example.com;
# Internal web application
location / {
auth_request /aut;
error_page 401 = @error401;
proxy_pass http://192.168.1.13:8080;
}
# Autentication application
location = /aut {
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_pass http://192.168.1.130:8080/Autentication/Auth;
}
# Redirect to login site
location @error401 {
return 302 http://example.com/Autentication/login;
}
}
# Proxy server to Login site
server {
listen 80;
listen [::]:80;
server_name example.com;
# Internal web application for login
location / {
proxy_pass http://192.168.1.130:8080;
}
}
如果用户请求通过 auth_request /aut;
进行身份验证,一切都很好,但如果我们强制 auth_request(在我们的 auth api 上)回答“HTTP 错误 401”,我们就会陷入两种不同的情况:
A) 如果用户刷新页面,一切正常:这意味着请求没有通过授权,客户端被重定向到我们的登录页面 http://example.com/Autentication/login
B) 如果用户尝试使用 javascript 从 api 获取数据,我们会在浏览器控制台中收到这 3 个错误:
ERROR .1)
Access to XMLHttpRequest at 'http://example.com/Autentication'
(redirected from 'http://internal.example.com/TestServer/servlet')
from origin 'http://internal.example.com' has been blocked by CORS policy:
Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response
ERROR 2)
Access to XMLHttpRequest at 'http://example.com/Autentication'
(redirected from 'http://internal.example.com/page.html')
from origin 'http://internal.example.com/' has been blocked by CORS policy:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
ERROR 3)
Access to XMLHttpRequest at 'http://example.com/Autentication'
(redirected from 'http://internal.example.com/TestServer/servlets)
from origin 'http://internal.example.com' has been blocked by CORS policy:
Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request.
我们尝试按照建议的 answer 在我们的 nginx myconfiguration.conf
中的位置块中添加此配置,但它没有解决我们的问题:
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET,OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always;
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET,Content-Range' always;
}
解决方法
经过几天在这里和那里测试一些更改后,我解决了问题:
在 tomcat 服务器上不需要配置(我的意思是在 tomcat 服务器上没有处理 cors 标头)。
我更改并足以让整个基础架构正常工作的是 NGINX 上的 myconfig.conf
文件。
这是正确的 myconfig.conf
:
# SERVER PROXY INTERNAL (can access only when auth_request is passed)----------------------------------------
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name internal.example.com;
# Proxy to internal tomcat with auth_request to /provaut
location / {
auth_request /prova_aut;
error_page 401 = @error401;
proxy_pass http://192.168.1.13:8080;
}
location = /prova_aut {
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_pass http://192.168.1.130:8080/Auth;
}
# Redirect to LOGIN
location @error401 {
return 302 http://example.com/Login;
}
}
# SERVER PROXY FOR LOGIN AND AUTH TOMCAT'S APP --------------------------
server {
listen 80;
listen [::]:80;
server_name example.com;
access_log /var/log/nginx/reverse-access.log;
error_log /var/log/nginx/reverse-error.log;
# Proxy to Authentication_app's tomcat
location / {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' 'http://internal.example.com' always;
add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always;
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' 'http://internal.example.com' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Allow-Methods' 'GET,Range' always;
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range,Access-Control-Allow-Origin,Access-Control-Allow-Credentials' always;
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' 'http://internal.example.com' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Allow-Methods' 'GET,Access-Control-Allow-Credentials' always;
}
proxy_pass http://192.168.1.130:8080;
}
}
真正的诀窍是在登录/身份验证服务器的 /location 块中添加以下两行
'Access-Control-Allow-Origin' 'http://internal.example.com' always;
和
'Access-Control-Allow-Credentials' 'true' always;
我真的希望这可以帮助别人;)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。