I am currently using the following code to set default credentials for UIWebView. This works fine in iOS 6.1 and earlier. However, in iOS 7 Beta 6 it does not work at all.
The web pages that I am trying to load use Windows Authentication. I am able to open them in Safari in iOS 7. However, when I run the below code and then open the URL in a UIWebView, I get an empty white rectangle and nothing ever loads! Like I said, this works perfectly in iOS 6.1 and earlier.
I also tried a second approach that involves using NSURLConnectionDelegate to hand off the credentials. This second approach also works fine in iOS 6.1 and earlier, but is broken in iOS 7.
Does anyone know why this is happening? Similar experiences? Thoughts?
// 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];
I had the same exact issue - an NSURLConnection to a Sharepoint site configured for Windows Authentication was working fine in iOS 6.1. In iOS 7 - regardless of whether I targeted and built the app for 6 or 7 - all authentications would seem to succeed (receiving the proper cookie) but still respond with a 401; all subsequent requests sent with the cookie would receive 401 as well.
I resolved the issue by dumping the didReceiveAuthenticationChallenge delegate protocol in favor of willSendRequestForAuthenticationChallenge. Implementing the 2nd delegate protocol means the first never gets called.
In your delegate, implement this delegate protocol:
- (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];
}
}
After I implemented this on a whim, my iOS 7 NTLM authentication issues disappeared.
Update: This issue appears to be fixed in iOS 7.0.3
I answered this in the Apple developer forum, but now that iOS7 is out of beta, I'll repost here. Currently Windows Authentication is broken in iOS7. I expect there will be a fix out shortly, but until then you can work around the problem by handling authentication challenges in your UIViewController that contains your UIWebView.
Essentially you
Below I'm loading a PDF, but the process works the same whatever your content type.
//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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With