2010-06-08 247 views
2

我無法獲得一個url請求來執行ssl url和基本身份驗證。我沒有檢查其他相關的問題,他們不似乎工作NSURLConnection SSL HTTP基本身份驗證

- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace { 
// NSLog(@"We are checking protection Space!"); 
    if([protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) 
    { 
     NSLog(@"Can Auth Secure Requestes!"); 
     return YES; 
    } 
    else if([protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodHTTPBasic]) 
    { 
     NSLog(@"Can Auth Basic Requestes!"); 
     return YES; 
     //return NO; 
    } 
    NSLog(@"Cannot Auth!"); 
    return NO; 


} 
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge: (NSURLAuthenticationChallenge *)challenge { 
    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) 
    { 
     NSLog(@"Trust Challenge Requested!"); 
     [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge]; 
     [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge]; 

    } 
    else if([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodHTTPBasic]) 
    { 
     NSLog(@"HTTP Auth Challenge Requested!"); 
     NSURLCredential *credential = [[NSURLCredential alloc] initWithUser:@"user" password:@"pass" persistence:NSURLCredentialPersistenceForSession]; 
     [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge]; 
     [credential release]; 
    } 

似乎無法找出什麼即時做錯了什麼。連接描述說安全連接失敗。我已經嘗試過簡單的ssl,沒有基本的工作正常。我也試過沒有ssl和基本的,它工作正常。

+0

你是否曾經進入了*連接:didReceiveAuthenticationChallenge:*方法?哪部分? (我已成功使用SSL進行基本身份驗證。) – Codo 2010-09-05 15:42:51

回答

1

實際上,它工作正常,問題與SSL證書有關。

3
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace { 
if([protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) 
{ 

    return YES; 
} 
else 
{ 
    if([protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodHTTPBasic]) 
    { 
     return YES; 
    } 
} 
    return NO; 


} 
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge: (NSURLAuthenticationChallenge *)challenge { 

if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) 
{ 
    [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge]; 
    [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge]; 

} 
else 
{ 
    if([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodHTTPBasic]) 
    { 

     NSURLCredential *creden = [[NSURLCredential alloc] initWithUser:@"USERNAME" password:@"PASSWORD" persistence:NSURLCredentialPersistenceForSession]; 


     [[challenge sender] useCredential:creden forAuthenticationChallenge:challenge]; 
     [creden release]; 
    } 
    else 
    { 
     [[challenge sender]cancelAuthenticationChallenge:challenge]; 

    } 
} 
} 
0

我認爲接受的答案可能最終錯誤地信任無效的服務器證書,因爲它不驗證服務器信任。

Apple's documentation for NSURLCredential credentialForTrust:表明您應該實際驗證服務器信任您使用它之前:

創建服務器信任證書之前,它是一個NSURLConnection的對象的委託或NSURLDownload對象來評價的責任相信。通過調用SecTrustEvaluate並將其從服務器的NSURLProtectionSpace對象的serverTrust方法中獲得的信任傳遞給它,來完成此操作。如果信任無效,則應使用cancelAuthenticationChallenge:取消認證質詢。

Apple's documentation for NSURLAuthenticationChallenge還指示應該如何考慮挑戰的proposedCredential

考慮到這將產生(ARC)的代碼是這樣的:

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge: (NSURLAuthenticationChallenge *)challenge 
{ 
    if (challenge.proposedCredential) 
    { 
     if (challenge.previousFailureCount == 0) 
     { 
      [challenge.sender useCredential:challenge.proposedCredential forAuthenticationChallenge:challenge]; 
     } 
     else 
     { 
      // The server has rejected the proposed credential, and 
      // you should use that credential to populate a password 
      // or certificate chooser dialog, then provide a new credential. 
      // You can create password-based credentials by calling the 
      // credentialWithUser:password:persistence: method or create 
      // certificate-based credentials with the 
      NSLog(@"Need to add code here to create new credential..."); 
     } 
    } 
    else if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) 
    { 
     NSLog(@"Trust Challenge Requested!"); 

     // As per NSURLCredential class reference, verify the server trust... 
     SecTrustResultType trustResult = kSecTrustResultInvalid; 
     const OSStatus status = SecTrustEvaluate(challenge.protectionSpace.serverTrust, &trustResult); 

     if (noErr == status && 
      (
       kSecTrustResultProceed == trustResult || 

       // https://developer.apple.com/library/mac/qa/qa1360/_index.html 
       kSecTrustResultUnspecified == trustResult 
      ) 
     ) 
     { 
      [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge]; 
      [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge]; 
     } 
     else 
     { 
      NSLog(@"Failed to verify server trust, cancelling..."); 
      [challenge.sender cancelAuthenticationChallenge:challenge]; 
     } 
    } 
    else if([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodHTTPBasic]) 
    { 
     NSLog(@"HTTP Auth Challenge Requested!"); 
     NSURLCredential *credential = [[NSURLCredential alloc] initWithUser:@"user" password:@"pass" persistence:NSURLCredentialPersistenceForSession]; 
     [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge]; 
    } 
}