setDefaultCredential 不适用于 iOS 7 中的 UIWebView,但在早期的 iOS 版本中工作



我目前正在使用以下代码为 UIWebView 设置默认凭据。 这在 iOS 6.1 及更早版本中工作正常。 但是,在iOS 7 Beta 6中,它根本不起作用。

我尝试加载的网页使用 Windows 身份验证。 我可以在iOS 7的Safari中打开它们。但是,当我运行以下代码然后在 UIWebView 中打开 URL 时,我得到一个空的白色矩形,并且没有任何内容加载! 就像我说的,这在iOS 6.1及更早版本中完美运行。

我还尝试了第二种方法,该方法涉及使用 NSURLConnectionDelegate 来移交凭据。 第二种方法在iOS 6.1及更早版本中也可以正常工作,但在iOS 7中被破坏了。

有谁知道为什么会这样? 类似的经历? 思潮?

// Authenticate
NSURLCredential *credential = [NSURLCredential credentialWithUser:@"myusername"
                                                         password:@"mypassword"
                                                      persistence:NSURLCredentialPersistenceForSession];
NSURLProtectionSpace *protectionSpace = [[NSURLProtectionSpace alloc]
                                         initWithHost:@"mysite.com"
                                         port:80
                                         protocol:@"http"
                                         realm:nil
                                         authenticationMethod:NSURLAuthenticationMethodDefault];
[[NSURLCredentialStorage sharedCredentialStorage] setDefaultCredential:credential forProtectionSpace:protectionSpace];

我遇到了同样的问题 - 为Windows身份验证配置的Sharepoint网站的NSURLConnection在iOS 6.1中工作正常。在 iOS 7 中 - 无论我是否针对 6 或 7 定位并构建了应用程序 - 所有身份验证似乎都会成功(接收正确的 cookie),但仍以 401 响应;使用 Cookie 发送的所有后续请求也将收到 401。

我通过转储didReceiveAuthenticationChallenge委托协议来支持willSendRequestForAuthenticationChallenge来解决这个问题。实现第二个委托协议意味着第一个委托协议永远不会被调用。

在委托中,实现以下委托协议:

- (void)connection:(NSURLConnection *)sender willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
   if ([challenge previousFailureCount] > 0]) {
       [[challenge sender] cancelAuthenticationChallenge:challenge];
   }else{
      NSURLCredential *credential = [NSURLCredential credentialWithUser:@"username" password:@"password" persistence:NSURLPersistenceForSession];
   [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
   }
}

在我一时兴起实现了这一点后,我的iOS 7 NTLM身份验证问题消失了。

更新:此问题似乎已在iOS 7.0.3中修复

我在苹果开发者论坛上回答了这个问题,但现在iOS7已经过测试版了,我将在这里重新发布。目前,iOS7中的Windows身份验证已损坏。我希望很快就会有修复程序,但在此之前,您可以通过在包含UIWebView的UIViewController中处理身份验证挑战来解决此问题。

本质上你

  1. 自己制作 NSURLRequest 和 NSURLConnection
  2. 处理连接:didReceiveAuthenticationChallenge:
  3. 在连接中:didReceivedResponse 手动将数据加载到 UIWebView 中

下面我正在加载一个PDF,但无论您的内容类型如何,该过程的工作方式都相同。

//Make sure you implement NSURLConnectionDelegate and NSURLConnectionDataDelegate in your header
@interface MyViewController ()
@property (weak, nonatomic) IBOutlet UIWebView *webView;
@property (strong, nonatomic) NSURLConnection *conn;
@property (strong, nonatomic) NSMutableData *pdfData;
@end
@implementation MyViewController 

//... all of your init and other standard UIViewController methods here...

//Method that loads UIWebview. You'll probably call this in viewDidLoad or somewhere similar... 
- (void) loadWebView {
    //Make Request manually with an NSURLConnection... 
    NSString *url = //Get your url
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
    self.conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
}
//#pragma mark - NSURLConnectionDelegate
//Handle authentication challenge (NSURLConnectionDelegate)
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
    if([challenge previousFailureCount] == 0) {
        NSString *username = //Get username
        NSString *password = //Get password
        //Use credentials to authenticate
        NSURLCredential *cred = [NSURLCredential credentialWithUser:username password:password persistence:NSURLCredentialPersistencePermanent];
        [[challenge sender] useCredential:cred forAuthenticationChallenge:challenge];
    } else {
        //Cancel authentication & connection
        [[challenge sender] cancelAuthenticationChallenge:challenge];
        [self.conn cancel];
        self.conn = nil;
    }
}
//#pragma mark - NSURLConnectionDataDelegate
//Received response (NSURLConnectionDataDelegate)
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    //Init data
    self.pdfData = [NSMutableData data];
}
//Collect data as it comes in (NSURLConnectionDataDelegate)
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    [self.pdfData appendData:data];
}
//Handle connection failure (NSURLConnectionDataDelegate)
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    //Clean up... 
    [self.conn cancel];
    self.conn = nil;
    self.pdfData = nil;
    //TODO: Notify user and offer next step...
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    //Finally, load data into UIWebview here (I'm loading a PDF)...
    [self.webView loadData:self.pdfData MIMEType:@"application/pdf" textEncodingName:@"utf-8" baseURL:nil];
}

@end

最新更新