2010-06-08 195 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]; 
    } 
}