2014-08-29 7 views
11

Mój serwer udostępnia kilka metod uwierzytelniania: NTLM i skrót.
Mój klient iOS nie obsługuje uwierzytelniania NTLM, więc zaimplementowałem delegata connection:willSendRequestForAuthenticationChallenge:, aby odrzucić NTLM, a następnie użyć poprawnego poświadczenia tylko dla wyzwalacza uwierzytelniania digest.
Wszystko działa poprawnie na iOS 7 do tej pory.NSURLConnectionDelegate willSendRequestForAuthenticationChallenge nie zostanie wywołany na iOS 8

Ale na iOS 8, znalazłem dziwne zachowanie:
Delegat connection:willSendRequestForAuthenticationChallenge: nie będzie wywoływany w większości czasu (95%) !!

mam ten błąd zamiast:

Error: Error Domain=NSPOSIXErrorDomain Code=54 "The operation couldn’t be completed. Connection reset by peer" 
UserInfo=0x16520fb0 {_kCFStreamErrorCodeKey=54, 
NSErrorPeerAddressKey=<CFData 0x16682e40 [0x2f752440]>{length = 16, capacity = 16, bytes = 0x10020d7eac12780b0000000000000000}, 
NSErrorFailingURLKey=http://SERVER_IP:SERVER_PORT/Tunnel/Message.aspx, 
NSErrorFailingURLStringKey=http://SERVER_IP:SERVER_PORT/Tunnel/Message.aspx, 
_kCFStreamErrorDomainKey=1} 

Tylko 5% czasu delegat jest poprawnie nazwie i pracy jak zwykle.

Poniżej przedstawiono sposób wyślę moją prośbę do serwera i obsługiwać wyzwanie uwierzytelnienia: prace

- (void)postRequest 
{ 
    NSString *IP = SERVER_IP; 
    int port = SERVER_PORT; 

    NSString *url = [NSString stringWithFormat:@"http://%@:%d/Tunnel/Message.aspx", IP, port]; 
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]]; 
    [request setHTTPMethod:@"POST"]; 
    [request setValue:@"application/xml" forHTTPHeaderField:@"Content-Type"]; 

    NSString *xml = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?><GetServerInfo></GetServerInfo>"]; 
    [request setHTTPBody: [xml dataUsingEncoding:NSUTF8StringEncoding]]; 

    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; 
} 

- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge 
{ 
    NSLog(@"%@", challenge.protectionSpace); 

    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodHTTPDigest]) 
    { 
     if ([challenge previousFailureCount] == 0) 
     { 
      [[challenge sender] useCredential:[NSURLCredential credentialWithUser:USERNAME 
                     password:PASSWORD 
                     persistence:NSURLCredentialPersistenceNone] 
        forAuthenticationChallenge:challenge]; 
     } 
     else 
     { 
      [[challenge sender] continueWithoutCredentialForAuthenticationChallenge:challenge]; 
     } 
    } 
    else 
    { 
     [[challenge sender] rejectProtectionSpaceAndContinueWithChallenge:challenge]; 
    } 
} 

Ci kod na iOS 7 willSendRequestForAuthenticationChallenge sprawdzony kilkakrotnie podczas wyzwaniu uwierzytelnienia, ale nawet nie nazywa się każdy raz na iOS 8!

Czy to może być błąd systemu iOS 8 lub coś się zmieniło od iOS 8?

+0

Zaktualizowano. Dzięki za przypomnienie. – rensakura

+0

Nawiasem mówiąc, użyłem twojego kodu na iOS 8 przeciwko mojemu podstawowemu serwerowi auth i działało dobrze (chociaż oczywiście zastąpiłem twój digest ref z podstawowym). Sugerowałbym oglądanie tego w [Charles] (http://charlesproxy.com) (lub podobnym narzędziu) i zobacz, jak reaguje twój serwer. Powtórz proces w iOS 7.1 i porównaj. Port i nazwa serwera wydają mi się podejrzane, ale mówisz, że kiedyś działały, więc domyślam się, że to nie to. – Rob

+1

Niestety pamiętam, jak ios7 łamie NTLM w wydaniu. Porównanie wymiany ruchu, zgodnie z wcześniejszym zaleceniem, będzie przydatne w przypadku wszelkich błędów zgłaszanych przez firmę Apple. Jeśli masz konto programisty, sprawdź # 17832727, a także następujące wątki na forum: https://devforums.apple.com/message/1042503#1042503, https://devforums.apple.com/message/1042505#1042505 – garthoid

Odpowiedz

2

Zdarzyło mi się to, gdy aktualizowałem aplikację na system iOS 7 na system iOS 8. Korzystaliśmy z Oracle SOA jako narzędzia pośredniego i po chwili przestaliśmy wywoływać metody delegatów. Poniżej pracował dla mnie zarówno w iOS8 i iOS7. (Z Xcode 6.1)

- (void) addBasicHTTPAuthenticationHeaders 
    { 
     NSString * wsUserName = @"userNameForWebService"; 
     NSString * wsPassword = @"passwordForWebService"; 

     NSString *authStr = [NSString stringWithFormat:@"%@:%@", wsUserName, wsPassword]; 
     NSData *authData = [authStr dataUsingEncoding:NSASCIIStringEncoding]; 
     NSString *authValue = [NSString stringWithFormat:@"Basic %@", [authData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithCarriageReturn]]; 
     [urlRequest setValue:authValue forHTTPHeaderField:@"Authorization"]; 
    }