2016-08-10 1 views
0

machen Nehmen wir an, ich habe zwei Server: Server A und Server B. Server A befinden sich die folgende Seite:Kann nicht POST/GET-Anforderung an HTTPS-Server mit HTTP-Authentifizierung durch XMLHttpRequest

<html> 
    <head> 
    <script type="text/javascript"> 
     var http = new XMLHttpRequest(); 
     console.log("XML Request object created."); 

     http.open("POST", 'https://serverb.com/file', true, 'user', 'pass'); 

     http.onreadystatechange = function() { 
     console.log("readystatechange: "+http.status+":"+http.readyState); 
     if (http.status == 200 && http.readyState == 4) { 
      alert(http.responseText); 
     } 
     } 

     http.send(); 
     console.log("http request sent."); 
    </script> 
    </head> 
</html> 

Mit folgendem Apache2 Konfiguration:

LoadModule ssl_module modules/mod_ssl.so 
LoadModule headers_module modules/mod_headers.so 

Listen 443 
<VirtualHost *:443> 

     Header always append Access-Control-Allow-Origin: "*" 
     Header set Access-Control-Allow-Credentials true 

     ServerAdmin [email protected] 
     DocumentRoot /var/www/html 

     ErrorLog ${APACHE_LOG_DIR}/error.log 
     CustomLog ${APACHE_LOG_DIR}/access.log combined 

     SSLEngine on 
     SSLCertificateFile "/home/vtcakavsmoace/Documents/webpass/cert.pem" 
     SSLCertificateKeyFile "/home/vtcakavsmoace/Documents/webpass/key.pem" 

</VirtualHost> 

Server B beherbergt eine Datei namens "Datei" und hat die folgende Apache2 Konfiguration:

LoadModule ssl_module modules/mod_ssl.so 
LoadModule headers_module modules/mod_headers.so 

Listen 443 
<VirtualHost *:443> 

    Header always append Access-Control-Allow-Origin: "*" 
    Header set Access-Control-Allow-Credentials true 

    ServerAdmin [email protected] 
    DocumentRoot /var/www/files 
    ErrorLog ${APACHE_LOG_DIR}/error.log 
    CustomLog ${APACHE_LOG_DIR}/access.log combined 

    <Directory "/var/www/files"> 
     AuthType Basic 
     AuthName "Restricted Content" 
     AuthUserFile /etc/apache2/.htpasswd 
     Require valid-user 
    </Directory> 
</VirtualHost> 

Hier erwartet der Server die HTTP-Authentifizierung für einen Benutzer namens 'user' mit einem Passwort 'pass'.

Jedes Mal, wenn jemand auf Server A verbindet, erhalten sie die folgende Fehlermeldung:

NS_ERROR_DOM_BAD_URI: Access to restricted URI denied 

signalisiert, dass Access-Control-Allow-Origin ist nicht in der Kopfzeile. Dies ist für beide Server nicht der Fall. Falls das nicht das Problem war, habe ich auch versucht, die Informationen über die Befehlszeile zu curlen, was erfolgreich war. Ich habe auch die http.open Linie versucht, zu ändern:

http.open("POST", 'https://user:[email protected]/file', true); 

Aber auch gescheitert.

Was mache ich hier falsch?

EDIT:

Falls es hilft, hier ist die Ausgabe von curl --verbose --head -u 'user:pass' https://serverb.com/file:

* Trying <redacted>... 
* Connected to <redacted> (<redacted>) port 443 (#0) 
* found 173 certificates in /etc/ssl/certs/ca-certificates.crt 
* found 697 certificates in /etc/ssl/certs 
* ALPN, offering http/1.1 
* SSL connection using TLS1.2/ECDHE_RSA_AES_128_GCM_SHA256 
* server certificate verification OK 
* server certificate status verification SKIPPED 
* common name: <redacted> (matched) 
* server certificate expiration date OK 
* server certificate activation date OK 
* certificate public key: RSA 
* certificate version: #3 
* subject: OU=<redacted>,OU=See www.rapidssl.com/resources/cps (c)15,OU=Domain Control Validated - RapidSSL(R),CN=<redacted> 
* start date: Wed, 06 May 2015 13:02:37 GMT 
* expire date: Mon, 08 May 2017 08:52:24 GMT 
* issuer: C=US,O=GeoTrust Inc.,CN=RapidSSL SHA256 CA - G3 
* compression: NULL 
* ALPN, server did not agree to a protocol 
* Server auth using Basic with user '<redacted>' 
> HEAD /<redacted>/file HTTP/1.1 
> Host: <redacted> 
> Authorization: Basic <redacted> 
> User-Agent: curl/7.47.0 
> Accept: */* 
> 
< HTTP/1.1 200 OK 
HTTP/1.1 200 OK 
< Date: Wed, 10 Aug 2016 11:30:36 GMT 
Date: Wed, 10 Aug 2016 11:30:36 GMT 
< Server: Apache/2.4.7 (Ubuntu) 
Server: Apache/2.4.7 (Ubuntu) 
< Access-Control-Allow-Origin: * 
Access-Control-Allow-Origin: * 
< Last-Modified: Tue, 09 Aug 2016 11:36:29 GMT 
Last-Modified: Tue, 09 Aug 2016 11:36:29 GMT 
< ETag: "<redacted>" 
ETag: "<redacted>" 
< Accept-Ranges: bytes 
Accept-Ranges: bytes 
< Content-Length: 45377 
Content-Length: 45377 
< Access-Control-Allow-Credentials: true 
Access-Control-Allow-Credentials: true 
< Content-Type: application/<redacted> 
Content-Type: application/<redacted> 

< 
* Connection #0 to host <redacted> left intact 

EDIT 2:

Ich habe weiter den Code geändert. Das Skript in der Webseite ist nun folgende:

var http = new XMLHttpRequest(); 
console.log("XML Request object created."); 

http.open("POST", 'https://serverb.com/file', true); 

http.withCredentials = true; 

http.setRequestHeader('Authorization', 'Basic '+btoa('user:pass')); 

http.onreadystatechange = function() { 
    console.log("readystatechange: "+http.status+":"+http.readyState); 
    if (http.status == 200 && http.readyState == 4) { 
    alert(http.responseText);  } 
    } 

http.send(); 
console.log("http request sent."); 

Statt nun einfach die Anforderung verweigert wird, bekomme ich ein 401-Statusserverside und eine 0-Status Client-Seite, was bedeuten, dass die Anmeldeinformationen nicht korrekt sind, auch wenn sie sind richtig.

EDIT 3:

Die folgende Bearbeiten öffnet das Authentifizierungsfenster in Chrome, aber in der folgenden, ein NS_ERROR_DOM_BAD_URI: Access to restricted URI denied Fehler ausgelöst wird.

var http = new XMLHttpRequest(); 
console.log("XML Request object created."); 

http.open("GET", 'https://serverb.com/file', true, 'user', 'pass'); 

http.withCredentials = true; 

http.onreadystatechange = function() { 
    console.log("readystatechange: "+http.status+":"+http.readyState); 
    if (http.status == 200 && http.readyState == 4) { 
    alert(http.responseText); 
    } 
} 

http.send(); 
console.log("http request sent."); 
+0

Soweit "Im Falle, dass dies nicht das Problem war, habe ich auch versucht, die Informationen über die Befehlszeile, die erfolgreich war": Sie verstehen, dass 'curl' oder andere nicht-Browser-Tool in der Lage sein wird Greife auf die Ressource zu, unabhängig davon, ob es einen 'Access-Control-Allow-Origin' gibt, richtig? Da "Access-Control-Allow-Origin" und alle anderen CORS-Header nur Browser betreffen, sind Browser die einzigen Anwendungen, die CORS-Einschränkungen erzwingen. Haben Sie tatsächlich die Antwortheader überprüft, um sicherzustellen, dass in der Antwort ein Header "Access-Control-Allow-Origin" vorhanden ist? – sideshowbarker

+0

@sideshowbarker Ja, ich verstehe, dass CORS nur für Browser gilt. Ich habe überprüft, dass die Benutzer/Passwort-Kombination funktioniert hat. Ich habe die rohen Antwortheader überprüft und sie zeigen (auf beiden) als 'Access-Control-Allow-Origin: * ' –

Antwort

0

Okay, also habe ich ein kleines Problem gelöst.

Da CORS mir NS_ERROR_DOM_BAD_URI: Access to restricted URI denied Probleme verursachte, habe ich CORS los und startete Proxy-Anfragen in Apache2-Konfigurationen weiter.

Index.html Endfassung:

<html> 
    <head> 
    <script type="text/javascript"> 
     var http = new XMLHttpRequest(); 
     console.log("XML Request object created."); 

     http.open("POST", 'file', true); 

     http.onreadystatechange = function() { 
     console.log("readystatechange: "+http.status+":"+http.readyState); 
     if (http.status == 200 && http.readyState == 4) { 
      alert(http.responseText); 
     } 
     } 

     http.send(); 
     console.log("http request sent."); 
    </script> 
    </head> 
</html> 

Server Eine endgültige Konfiguration:

LoadModule ssl_module modules/mod_ssl.so 
LoadModule headers_module modules/mod_headers.so 
LoadModule rewrite_module modules/mod_rewrite.c 
LoadModule proxy_module modules/mod_proxy.so 
LoadModule proxy_http_module modules/mod_proxy_http.so 
LoadModule auth_basic_module modules/mod_auth_basic.c 

Listen 443 
<VirtualHost *:443> 

     Header always append Access-Control-Allow-Origin: "*" 
     Header set Access-Control-Allow-Credentials true 

     ServerAdmin [email protected] 
     DocumentRoot /var/www/html 

     ErrorLog ${APACHE_LOG_DIR}/error.log 
     CustomLog ${APACHE_LOG_DIR}/access.log combined 

     SSLEngine on 
     SSLCertificateFile "/path/to/cert.pem" 
     SSLCertificateKeyFile "/path/to/key.pem" 

     ProxyRequests Off 
     <Proxy *> 
       Order deny,allow 
       Allow from all 
     </Proxy> 

     SSLProxyEngine On 
     SSLProxyCheckPeerCN on 
     SSLProxyCheckPeerExpire on 

     # Adding a prefix for googling purposes. 
     ProxyPassMatch "^/(prefix.*file.*.jpg)$" "https://serverb.com/$1" 
     ProxyPassReverse "/" "https://serverb.com/" 

     <LocationMatch "^/prefix.*file.*.jpg$"> 

      # Pass the credentials 
      AuthBasicFake "user" "pass" 
      Order allow,deny 
      Allow from all 

     </LocationMatch> 
</VirtualHost> 

Server B Endkonfiguration:

LoadModule ssl_module modules/mod_ssl.so 
LoadModule headers_module modules/mod_headers.so 

Listen 443 
<VirtualHost *:443> 

    Header always append Access-Control-Allow-Origin: "*" 
    Header set Access-Control-Allow-Credentials true 

    ServerAdmin [email protected]lhost 
    DocumentRoot /var/www/files 
    ErrorLog ${APACHE_LOG_DIR}/error.log 
    CustomLog ${APACHE_LOG_DIR}/access.log combined 

    <Directory "/var/www/files"> 
     AuthType Basic 
     AuthName "Restricted Content" 
     AuthUserFile /etc/apache2/.htpasswd 
     Require valid-user 
    </Directory> 
</VirtualHost> 

Eine weitere gute Sache über diese Methode ist, dass der Endbenutzer nie sieht die Passwort, also gibt es keine Autorisierung Offenlegung.

Verwandte Themen