2013-08-03 22 views
14
NSURLConnection/CFURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813) 

Sehr, sehr frustrierend! Ich habe mir damit stundenlang die Haare gezogen. Ich verwende ein selbstsigniertes Zertifikat auf meinem Linode-Server. Der Port ist 8000, konnte nicht auf 443 arbeiten. Ich glaube nicht, dass dies der Grund ist. Hier ist mein Code, es ist 99% vorformulierten:iOS HTTPS-Anfragen 101

NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"https://www.myserver.com:8000/test.json"]]; 
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES]; 

Am Boden:

#pragma mark NSURLConnectionDelegate 

- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace { 
    NSLog(@"protectionSpace: %@", [protectionSpace authenticationMethod]); 

    // We only know how to handle NTLM authentication. 
    if([[protectionSpace authenticationMethod] isEqualToString:NSURLAuthenticationMethodNTLM]) 
     return YES; 

    // Explicitly reject ServerTrust. This is occasionally sent by IIS. 
    if([[protectionSpace authenticationMethod] isEqualToString:NSURLAuthenticationMethodServerTrust]) 
     return NO; 

    return NO; 
} 

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { 
    [[challenge sender] continueWithoutCredentialForAuthenticationChallenge:challenge]; 
} 

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { 
    NSLog(@"%@", response); 
} 

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { 
    NSLog(@"%@", data); 
} 

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { 
    NSLog(@"didFailWithError"); 
    NSLog([NSString stringWithFormat:@"Connection failed: %@", [error description]]); 
} 

OMG HELP!

UPDATE

es mit diesem Delegatmethode gearbeitet. Ich erhalte die Antwort, aber es gibt ein Problem.

- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { 
    [[challenge sender] useCredential:[NSURLCredential 
             credentialWithUser:@"user" 
             password:@"password" 
             persistence:NSURLCredentialPersistencePermanent] forAuthenticationChallenge:challenge]; 

} 

Die "Benutzer" und "Passwort", die ich zur Verfügung gestellt habe, sind völlig zufällig und werden nicht vom Server überprüft. Wie kann ich die Anmeldedaten vor dem Akzeptieren der Verbindung auf meinem Server überprüfen?

EDIT: Ich bin ein Node.js Server

+0

„Der‚Benutzer‘und‚Passwort‘, die ich zur Verfügung gestellt habe völlig zufällig sind und nicht vom Server überprüft“ - das ist eine andere Frage. Sie sollten es als separate Frage stellen und vielleicht auf diese Frage zurückkommen. Die Linode-Konfiguration ist möglicherweise nicht am Thema, sodass Sie möglicherweise zu Super User oder Server Fault wechseln müssen. (Und Sie sollten wahrscheinlich Fonix Antwort akzeptieren, da es Ihnen geholfen hat, das Problem zu lösen). – jww

Antwort

2

nicht sicher, ob dies tatsächlich das Problem beheben laufen, aber es kann helfen. Sie sollten verwenden

– connection:willSendRequestForAuthenticationChallenge: 

seit die anderen Methoden veraltet sind. in der Übersicht über die NSURLConnectionDelegate protocol

+0

Fast funktioniert, siehe meine aktualisierte Frage –

+0

Leider bin ich ein bisschen ein Noob mit dieser Authentifizierung Zeug, so bin ich nicht sicher – Fonix

8

einen Blick die entsprechende Fehlerbeschreibung Wie Sie Hilfe bekommen kann:

Also, zunächst die Fehlerdomäne kCFStreamErrorDomainSSL bedeutet, dass der Fehlercode ein SSL-Fehlercode ist wie in Sicherheit/SecureTransport.h definiert :

kCFStreamErrorDomainSSL, -9813 bedeutet:

errSSLNoRootCert = -9813, /* cert chain not verified by root */

und das bedeutet einfach, Sie keine vertrauenswürdige root-Zertifikat und die conne haben ction schlägt aufgrund dieses Authentifizierungsfehlers fehl.

Geben Sie ein Stammzertifikat auf dem Gerät für die Server Trust-Authentifizierung und Sie sind in Ordnung.

Es gibt einige Ansätze zur Implementierung der Server-Vertrauensauthentifizierung mit selbstsignierten Zertifikaten, die eine sicherer als die andere.

Der einfachste Ansatz erfordert ein selbstsigniertes Zertifikat, das im Paket der App gespeichert, dann abgerufen und einfach Byte-verglichen wird. Hier ein Beispiel:

Implementing server trust authentication with a self-signed certificate.

Diese müssen auch gelesen werden: Technical Note TN2232 HTTPS Server Trust Evaluation und Technical Q&A QA1360 Describing the kSecTrustResultUnspecified error.

Der bevorzugtere Ansatz ist die Verwendung einer CA (Certificate Authority), die Sie selbst sein können. Das heißt, Sie erstellen eine eigene Zertifizierungsstelle und Ihre mit dieser Zertifizierungsstelle signierten Zertifikate.

Die Schritte sind ähnlich:

  1. Bundel die DER-Datei Ihres Root-Zertifikat der CA in Ihrer Anwendung.
  2. Behandeln Sie den Server Vertrauen Authentifizierung wie folgt:

    1. die Authentifizierungsanfrage erhalten
    2. das Vertrauen Objekt aus der Herausforderung aus den Daten in Ihrem Bündel
    3. erstellen ein Zertifikat Objekt abrufen
    4. setzen die Zertifikatobjekt als Anker für das Vertrauensobjekt mit der Funktion SecTrustSetAnchorCertificates.
    5. bewerten das Vertrauen
+4

Hier ist die URL für die Entschlüsselung anderer Fehlercodes ... http://www.opensource.apple.com/ Quelle/libsecurity_ssl/libsecurity_ssl-36800/lib/SecureTransport.h – cat

Verwandte Themen