Попробуйте использовать sharedCredentialStorage для всех доменов, которые необходимо аутентифицировать.
Вот рабочий пример для UIWebView, который был протестирован на Windows IIS с включенной только базовой аутентификацией
Это как добавить учетные данные вашего сайта:
NSString* login = @"MYDOMAIN\\myname";
NSURLCredential *credential = [NSURLCredential credentialWithUser:login
password:@"mypassword"
persistence:NSURLCredentialPersistenceForSession];
NSURLProtectionSpace *protectionSpace = [[NSURLProtectionSpace alloc]
initWithHost:@"myhost"
port:80
protocol:@"http"
realm:@"myhost" // check your web site settigns or log messages of didReceiveAuthenticationChallenge
authenticationMethod:NSURLAuthenticationMethodDefault];
[[NSURLCredentialStorage sharedCredentialStorage] setDefaultCredential:credential
forProtectionSpace:protectionSpace];
[protectionSpace release];
Редактировать: тот же код в Swift 4
let login = "MYDOMAIN\\myname"
let credential = URLCredential(user:login, password:"mypassword", persistence:.forSession)
let protectionSpace = URLProtectionSpace(host:"myhost", port:80, protocol:"http", realm:"myhost", authenticationMethod:NSURLAuthenticationMethodDefault)
URLCredentialStorage.shared.setDefaultCredential(credential, for:protectionSpace)
Предполагается, что ваш webView теперь работает, если он не работает, используйте следующий код для отладки, особенно проверьте сообщения журнала didReceiveAuthenticationChallenge.
#import "TheSplitAppDelegate.h"
#import "RootViewController.h"
@implementation TheSplitAppDelegate
@synthesize window = _window;
@synthesize splitViewController = _splitViewController;
@synthesize rootViewController = _rootViewController;
@synthesize detailViewController = _detailViewController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
// Add the split view controller's view to the window and display.
self.window.rootViewController = self.splitViewController;
[self.window makeKeyAndVisible];
NSLog(@"CONNECTION: Add credentials");
NSString* login = @"MYDOMAIN\\myname";
NSURLCredential *credential = [NSURLCredential credentialWithUser:login
password:@"mypassword"
persistence:NSURLCredentialPersistenceForSession];
NSURLProtectionSpace *protectionSpace = [[NSURLProtectionSpace alloc]
initWithHost:@"myhost"
port:80
protocol:@"http"
realm:@"myhost" // check your web site settigns or log messages of didReceiveAuthenticationChallenge
authenticationMethod:NSURLAuthenticationMethodDefault];
[[NSURLCredentialStorage sharedCredentialStorage] setDefaultCredential:credential forProtectionSpace:protectionSpace];
[protectionSpace release];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://myhost/index.html"]
cachePolicy:NSURLRequestReloadIgnoringCacheData
timeoutInterval:12
];
NSLog(@"CONNECTION: Run request");
[[NSURLConnection alloc] initWithRequest:request delegate:self];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application
{
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
}
- (void)applicationWillTerminate:(UIApplication *)application
{
}
- (void)dealloc
{
[_window release];
[_splitViewController release];
[_rootViewController release];
[_detailViewController release];
[super dealloc];
}
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge;
{
NSLog(@"CONNECTION: got auth challange");
NSString* message = [NSString stringWithFormat:@"CONNECTION: cred cout = %i", [[[NSURLCredentialStorage sharedCredentialStorage] allCredentials] count]];
NSLog(message);
NSLog([connection description]);
NSLog([NSString stringWithFormat:@"CONNECTION: host = %@", [[challenge protectionSpace] host]]);
NSLog([NSString stringWithFormat:@"CONNECTION: port = %i", [[challenge protectionSpace] port]]);
NSLog([NSString stringWithFormat:@"CONNECTION: protocol = %@", [[challenge protectionSpace] protocol]]);
NSLog([NSString stringWithFormat:@"CONNECTION: realm = %@", [[challenge protectionSpace] realm]]);
NSLog([NSString stringWithFormat:@"CONNECTION: authenticationMethod = %@", [[challenge protectionSpace] authenticationMethod]]);
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
// release the connection, and the data object
[connection release];
// inform the user
NSLog(@"CONNECTION: failed! Error - %@ %@",
[error localizedDescription],
[[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]);
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;
{
NSLog(@"CONNECTION: received response via nsurlconnection");
}
- (BOOL)connectionShouldUseCredentialStorage:(NSURLConnection *)connection;
{
NSLog(@"CONNECTION: USE!");
return YES;
}
@end
Окончательное решение для аутентификации WebView было основано на реализации пользовательского протокола. Все протоколы зарегистрированы как стек, поэтому, если вы переопределите протокол HTTP, он будет перехватывать все запросы, поступающие из webView, поэтому вы должны проверить атрибуты, связанные с входящим запросом, перепаковать его в новый запрос и отправить его снова через ваше собственное соединение. Поскольку вы в стеке, ваш запрос немедленно возвращается к вам, и вы должны его игнорировать. Таким образом, он сводит стек протоколов к реальной реализации протокола HTTP, поскольку ваш запрос не аутентифицирован, вы получите запрос аутентификации. А после аутентификации вы получите реальный ответ от сервера, поэтому вы перепаковываете ответ и отвечаете на оригинальный запрос, полученный от webView, и все.
Не пытайтесь создавать новые тела запросов или ответов, вам нужно просто отправить их заново. Конечный код будет приблизительно 30-40 строк кода, и это довольно просто, но требует много отладки и проверки.
К сожалению, я не могу предоставить здесь код, поскольку я уже назначен другому проекту, я просто хотел сказать, что мое сообщение неверно, оно застревает, когда пользователь меняет пароль.