NSURLConnection, NSURLRequest, cert non attendibile e l'autenticazione degli utenti
-
05-10-2019 - |
Domanda
giorno a tutti,
mi è stato tentato di scrivere un'applicazione che fa un po 'ottiene da un telecomando servizio Web che richiede l'autenticazione. Il mio problema principale è che la maggior parte di questi server remoti (e ci sono un sacco di loro) non hanno certificati validi. Ho codice per accettare il certificato non valido e il codice per rispondere alla sfida con la corretta uname & pass ( sotto). Il problema che sto avendo è sempre il due a giocare insieme. Io non riesco a trovare un modo per inviare la sfida sia NSURLCredential
s o un modo i callback correttamente la catena. Quando provo a loro catena non riesco a ottenere la mia NSURLRequest
alla chiamata didReceiveAuthenticationChallenge
due volte.
Ogni pensiero sarebbe apprezzato!
Codice per l'autenticazione ...
-(void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
if(!hasCanceled){
if ([challenge previousFailureCount] == 0) {
NSURLCredential *newCredential;
newCredential=[NSURLCredential credentialWithUser:_username password:_password persistence:NSURLCredentialPersistenceNone];
[[challenge sender] useCredential:newCredential forAuthenticationChallenge:challenge];
}
else {
[[challenge sender] cancelAuthenticationChallenge:challenge];
NSLog(@"Bad Username Or Password");
badUsernameAndPassword = YES;
finished = YES;
}
}
}
Soluzione
È possibile rispondere solo a un NSURLAuthenticationChallenge
con una credenziale per quella sfida. È possibile determinare quale tipo di sfida che hai ricevuto utilizzando:
[[challenge protectionSpace] authenticationMethod]
I valori possibili sono documentato qui . Nel caso di un certificato di server non valido, il metodo di autenticazione sarà NSURLAuthenticationMethodServerTrust
. Nel codice, si dovrebbe verificare il metodo di autenticazione e rispondere in modo appropriato.
if ([challenge previousFailureCount] > 0) {
// handle bad credentials here
[[challenge sender] cancelAuthenticationChallenge:challenge];
return;
}
if ([[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodServerTrust) {
// check if the user has previously accepted the certificate, otherwise prompt
} else if ([[challenge protectionSpace] authenticationMethod] == /* your supported authentication method here */) {
[[challenge sender] useCredential:/* your user's credential */ forAuthenticationChallenge:challenge];
}
Non è un errore se non si ottiene sia l'autenticazione sfida ogni volta. È possibile memorizzare nella cache le credenziali quando li si crea. Se lo fai, non sarà necessariamente richiesto di nuovo.