Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

redirect - Nginx with auth_request_module to reverse proxied app throws CORS errors

I am developing a nginx server to work as a reverse proxy to a local webapp only when user is authenticated. Here is my nginx myconfiguration.conf flie inside 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;
    }
}

If users requests are authenticated through the auth_request /aut; everithing works great, but if we force the auth_request (on our auth api) to answer 'HTTP error 401' we slip into 2 different situations:

A) if the user refresh the page, everithing works: it means that the request do not pass the authorization and the client is redirected to our login page http://example.com/Autentication/login

B) if the user tries to fetch data from an api using javascript we receive this 3 errors in the browser console:

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.

We tried, as suggested here, to add this configurations in our nginx myconfiguration.conf inside the location block but it didn't solved our problem:

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, 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-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, 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-Expose-Headers' 'Content-Length,Content-Range' always;
}
question from:https://stackoverflow.com/questions/65849169/nginx-with-auth-request-module-to-reverse-proxied-app-throws-cors-errors

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

After few days of testing some change here and there I SOLVED the problem: No configuration needed on tomcat server (i mean no cors headers handled on tomcat server). What i changed and was enough to let the whole infrastructure work was the myconfig.conf file on NGINX.

Here is the correct 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, 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-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, 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-Expose-Headers' 'Content-Length,Content-Range,Access-Control-Allow-Origin,Access-Control-Allow-Credentials' always;
           }
           proxy_pass http://192.168.1.130:8080;
         }
}

What really made the trick was adding the two lines below in the /location block of the Login/Auth server 'Access-Control-Allow-Origin' 'http://internal.example.com' always; and 'Access-Control-Allow-Credentials' 'true' always;

I Really hope this can help someone else ;)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...