403 Запрещено по запросу CORS от местного - PullRequest
0 голосов
/ 12 марта 2019

Я работаю с Gluu Server и пытаюсь получить конфигурацию OpenID Connect от конечной точки /.well-known/openid-configuration через запрос CORS / AJAX (для использования с приложением Angular).Однако, когда я пытаюсь запросить конечную точку из локально размещенного файла приложения / HTML-файла с XHR, запрашивающим конечную точку, я получаю ошибку 403 Forbidden.

Кажется, что это происходит, только когда запрос происходит из локального контекстасервер разработки Angular или локальный HTML-файл, запрашивающий конечную точку.Если я открываю тот же HTML-файл, который выполняет запрос AJAX, размещенный на сервере, он работает.

Тестовый HTML-файл выглядит следующим образом

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
    <div id="content"></div>
    <script type="text/javascript">
        var url = 'https://example.com/.well-known/openid-configuration';

        var req = new XMLHttpRequest();

        req.open('GET', url, true);
        req.setRequestHeader('Content-Type', 'application/json');

        req.onload = () => {
            if (req.status >= 200 && req.status < 400) {
                console.log('[XHR SUCCESS]');
                var el = document.getElementById('content');
                el.innerHTML = req.responseText;
            } else {
                console.log('[XHR ERROR]', req);
            }
        }

        req.onerror = () => {
            console.log('[XHR CONNECTION ERROR]');
        }
        req.send();
    </script>
</body>
</html>

Запрос из локального файла

Как упоминалось выше, при запросе из локального HTML-файла я получаю ошибку 403 Forbidden.

В консоли браузера (Chrome) выводятся две ошибки:

Failed to load resource: the server responded with a status of 403 (Forbidden)
Access to XMLHttpRequest at 'https://example.com/.well-known/openid-configuration' from origin 'null' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.

Единственный найденный мной вывод на сервере, относящийся к этому, находится в файле /var/log/apache2/other_vhosts_access.log:

example.com:443 <IP> - - [11/Mar/2019:10:45:20 +0000] "OPTIONS /.well-known/openid-configuration HTTP/1.1" 403 3763 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36"

Сервер получает следующее (от модуля log_forensicдля Apache) при запросе из локальной системы:

OPTIONS /.well-known/openid-configuration HTTP/1.1|Host:example.com|Connection:keep-alive|Pragma:no-cache|Cache-Control:no-cache|Access-Control-Request-Method:GET|Origin:null|User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36|Access-Control-Request-Headers:content-type|Accept:*/*|Accept-Encoding:gzip, deflate, br|Accept-Language:en-US,en;q=0.9

Запрос из файла, размещенного на сервере

При выполнении тех же действий, что и выше, но с файлом HTML, размещенным на сервере, запросзавершается успешно.

Вывод в журнал доступа:

example.com:443 <IP> - - [11/Mar/2019:11:06:46 +0000] "OPTIONS /.well-known/openid-configuration HTTP/1.1" 200 779 "http://example.org/xhr-cors.html" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36"
example.com:443 <IP> - - [11/Mar/2019:11:06:46 +0000] "GET /.well-known/openid-configuration HTTP/1.1" 200 6629 "http://example.org/xhr-cors.html" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36"

С log_forensic:

OPTIONS /.well-known/openid-configuration HTTP/1.1|Host:example.com|Connection:keep-alive|Access-Control-Request-Method:GET|Origin:http%3a//example.org|User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36|Access-Control-Request-Headers:content-type|Accept:*/*|Referer:http%3a//example.org/xhr-cors.html|Accept-Encoding:gzip, deflate, br|Accept-Language:en-US,en;q=0.9

GET /.well-known/openid-configuration HTTP/1.1|Host:example.com|Connection:keep-alive|Origin:http%3a//example.org|User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36|Content-Type:application/json|Accept:*/*|Referer:http%3a//example.org/xhr-cors.html|Accept-Encoding:gzip, deflate, br|Accept-Language:en-US,en;q=0.9

Конфигурация Apache

Конфигурация для Apacheна сервере

<VirtualHost  *:80>
        ServerName example.com
        Redirect  / https://example.com/
        DocumentRoot "/var/www/html/"
RewriteEngine on
RewriteCond %{SERVER_NAME} =example.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>

<VirtualHost *:443>
        DocumentRoot "/var/www/html/"
        ServerName example.com:443

        LogLevel warn
        SSLEngine on
        SSLProtocol -all +TLSv1.1 +TLSv1.2
        SSLHonorCipherOrder On
        SSLCipherSuite ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:DHE-RSA-AES128-SHA256:DHE-DSS-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:DHE-RSA-AES128-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK

#               SetEnv proxy-nokeepalive 1
        SetEnv proxy-initial-not-pooled 1
        Timeout 60
                ProxyTimeout 60

        # Security headers
#        Header always append X-Frame-Options SAMEORIGIN
                Header always set X-Xss-Protection "1; mode=block"
                Header always set X-Content-Type-Options nosniff
#        Header always set Content-Security-Policy "default-src 'self' 'unsafe-inline' https://example.com"
        Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"

        Header edit Set-Cookie ^((?!session_state).*)$ $1;HttpOnly
        SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown downgrade-1.0 force-response-1.0

                # Unset X-ClientCert to make sure that we not get certificate in request
        RequestHeader unset X-ClientCert

                # Turn off support for true Proxy behaviour as we are acting as a transparent proxy
        ProxyRequests Off

                # Turn off VIA header as we know where the requests are proxied
        ProxyVia Off

                # Turn on Host header preservation so that the servlet container
                # can write links with the correct host and rewriting can be avoided.
        ProxyPreserveHost On

                # Preserve the scheme when proxying the request to Jetty
                RequestHeader set X-Forwarded-Proto "https" env=HTTPS

                Header unset ETag
        FileETag None

        RedirectMatch ^(/)$ /identity/

                # Set the permissions for the proxy
                <Proxy *>
                  AddDefaultCharset off
                  Order deny,allow
                  Allow from all
                </Proxy>

        <Location /oxauth>
                ProxyPass http://localhost:8081/oxauth retry=5 connectiontimeout=60 timeout=60
#                Header set Access-Control-Allow-Origin "*"
                Order deny,allow
                Allow from all
        </Location>

        <LocationMatch /oxauth/auth/cert/cert-login>
            SSLVerifyClient optional_no_ca
            SSLVerifyDepth 10
            SSLOptions -StdEnvVars +ExportCertData

                        # Forward certificate to destination server
            RequestHeader set X-ClientCert %{SSL_CLIENT_CERT}s
        </LocationMatch>

        <Location /idp>
                ProxyPass http://localhost:8086/idp retry=5 connectiontimeout=60 timeout=60
                Order deny,allow
                Allow from all
        </Location>

        <Location /identity>
                ProxyPass http://localhost:8082/identity retry=5 connectiontimeout=60 timeout=60
                Order deny,allow
                Allow from all
        </Location>

        <Location /cas>
                ProxyPass http://localhost:8083/cas retry=5 connectiontimeout=60 timeout=60
                Order deny,allow
                Allow from all
        </Location>

        <Location /oxauth-rp>
                ProxyPass http://localhost:8085/oxauth-rp retry=5 connectiontimeout=60 timeout=60
                Order deny,allow
                Allow from all
        </Location>

        <Location /asimba>
                ProxyPass http://localhost:8084/asimba retry=5 connectiontimeout=60 timeout=60
                Order deny,allow
                Allow from all
        </Location>

        <Location /passport>
                ProxyPass http://localhost:8090/passport retry=5 connectiontimeout=60 timeout=60
                Order deny,allow
                Allow from all
        </Location>

        <Location /casa>
                ProxyPass http://localhost:8091/casa retry=5 connectiontimeout=60 timeout=60
                Order deny,allow
                Allow from all
        </Location>

       <LocationMatch "/.well-known/openid-configuration">
               ProxyPass http://localhost:8081/oxauth/.well-known/openid-configuration
               Header set Access-Control-Allow-Origin "*"
       </LocationMatch>

#                        ProxyPass /.well-known/openid-configuration http://localhost:8081/oxauth/.well-known/openid-configuration
ProxyPass /.well-known/simple-web-discovery http://localhost:8081/oxauth/.well-known/simple-web-discovery
ProxyPass        /.well-known/webfinger http://localhost:8081/oxauth/.well-known/webfinger
        ProxyPass        /.well-known/uma2-configuration http://localhost:8081/oxauth/restv1/uma2-configuration
        ProxyPass        /.well-known/fido-configuration http://localhost:8081/oxauth/restv1/fido-configuration
        ProxyPass        /.well-known/fido-u2f-configuration http://localhost:8081/oxauth/restv1/fido-configuration
        ProxyPass        /.well-known/scim-configuration http://localhost:8082/identity/restv1/scim-configuration
        ServerAlias        example.com
        SSLCertificateFile        /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>

Я закомментировал

ProxyPass /.well-known/openid-configuration http://localhost:8081/oxauth/.well-known/openid-configuration

и введена директива

<LocationMatch "/.well-known/openid-configuration">
        ProxyPass http://localhost:8081/oxauth/.well-known/openid-configuration
        Header set Access-Control-Allow-Origin "*"
</LocationMatch>

для добавления заголовка (ов) CORS.

Другое

Другие вещи, которые я пытался изобразитьЧто это за проблема:

  • Выполнен запрос GET к конечной точке через Почтальон, который успешно завершен.
  • Выполнен запрос OPTIONS к конечной точке через Почтальон, которыйзавершен успешно.

Я был бы очень признателен за некоторые замечания по этому вопросу, так как это довольно сильно ошарашило меня, и я не могу работать из локальной среды, когда разработка трудоемка.Если требуется какое-либо разъяснение, пожалуйста, дайте мне знать.

1 Ответ

0 голосов
/ 13 марта 2019

Оказывается, эта проблема была объединением двух не связанных между собой вещей.

Во-первых, и это в основном гипотеза, кажется , что Chrome блокирует запросы из локального файла (файла HTML) и просто предоставляет вывод, который, на мой взгляд, очень запутанный. То есть 403 ошибка может быть, потому что Chrome каким-то образом блокирует запрос CORS. Я попытался запустить Chrome с различными флагами, например --disable-web-security и --allow-file-access-from-files, но это не изменило вывод из локального HTML-файла. Таким образом, локальный запрос файла все еще терпит неудачу, и я не знаю точную причину. Но, поскольку это было только для тестирования, для меня это не так актуально.

Во-вторых, ошибочная реализация в перехватчике в проекте Angular перезаписала все заголовки для запросов. После исправления локальный сервер смог запросить конечную точку.

Так уж вышло, что результаты двух разных выпусков выглядели практически одинаково, что меня отбросило.

...