Il mio server fornisce diversi metodi di autenticazione: NTLM e digest.
Il mio client iOS non gestisce l'autenticazione NTLM, quindi implemento il delegato connection:willSendRequestForAuthenticationChallenge:
per rifiutare NTLM, quindi utilizzo le credenziali corrette solo per la sfida di autenticazione digest.
Tutto funziona correttamente su iOS 7 finora.NSURLConnectionDelegate willSendRequestForAuthenticationChallenge non verrà chiamato su iOS 8
Ma su iOS 8, ho trovato un comportamento strano:
il delegato connection:willSendRequestForAuthenticationChallenge:
non verrà chiamato al più tempo (95%) !!
ho ottenuto questo errore invece:
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}
Solo il 5% di tempo il delegato si chiama e il lavoro come al solito in modo corretto.
qui sotto mostra come mando la mia richiesta al server e gestire la richiesta di autenticazione: il lavoro
- (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];
}
}
Coloro codice su iOS 7, willSendRequestForAuthenticationChallenge
ottenere chiamato più volte durante la richiesta di autenticazione, ma nemmeno chiamato alcuna una volta su iOS 8!
Potrebbe essere un bug di iOS 8 o qualcosa di cambiato da iOS 8?
Aggiornato. Grazie per ricordare. – rensakura
Per inciso, ho usato il tuo codice su iOS 8 contro il mio server di autenticazione di base e ha funzionato correttamente (anche se ovviamente ho sostituito il tuo riferimento ref con basic). Ti suggerisco di guardare questo in [Charles] (http://charlesproxy.com) (o strumento simile) e vedere come il tuo server sta rispondendo. Ripeti il processo in iOS 7.1 e confronta. La porta e il nome del server mi sembrano sospetti, ma tu dici che era abituato a funzionare, quindi credo che non sia così. – Rob
Purtroppo ricordo che ios7 ha interrotto NTLM in rilascio. Confrontare lo scambio di traffico come precedentemente raccomandato sarà utile in qualsiasi bug sollevato con Apple. Se hai un account sviluppatore, controlla # 17832727, nonché i seguenti thread del forum https://devforums.apple.com/message/1042503#1042503, https://devforums.apple.com/message/1042505#1042505 – garthoid