Я пытался решить это в течение некоторого времени, но безуспешно. Такие вопросы, как , этот здесь или вопросы использования аутентификации Apple и других блогов проливают свет, но не все.
Моя основная проблема, которую я хотел бы решить, заключается в следующем:
Я успешно аутентифицируюсь на своем сервере, используя NSURLConnection с его делегатами и NSURLCredential с NSURLProtectionSpace и NSURLCredentialStorage. Однако даже если я установил постоянство NSURLCredential в NSURLCredentialPersistencePermanent, я случайно получаю вызовы проверки подлинности (401 и затем 200) с моего сервера после того, как уже предоставил свои учетные данные в первый раз - не должно ли это быть так, как NSURLCredentialPersistencePermanent длится постоянно? Случайная вещь - это то, что просто не имеет смысла.
Иногда это работает, и последующие вызовы на сервер возвращаются нормально с 200. С другой стороны, это не так, и возвращается 401 с 200. Майк Абдулла хорошо описал процесс за здесь . Итак, мое первое предположение состояло в том, что процесс возврата аутентификации 401 и получения 200 является стандартной процедурой и не может быть устранен. Однако иногда я могу устранить 401. Поэтому я, кажется, что-то упускаю.
Запросы, которые я посылаю, - это некоторые GET и два POST. Дело в том, что один POST загружает множество данных. При получении 401 данные все еще загружаются в нирвану, после аутентификации они снова загружаются.
Мое альтернативное решение было бы предотвратить передачу данных в любом случае при получении 401. Я сейчас работаю над этим, что кажется хитрым, потому что иногда 401 не возвращается, как уже упоминалось ранее.
Если это не понятно, я добавлю любую информацию. Я предполагаю, что либо я использую весь NSURLCredential, либо неправильно, либо способ аутентификации, сначала получая 401, а затем 200, и это не исключено.
Выдержки из моего кода ниже:
loginCredential = [NSURLCredential credentialWithUser:@"foo"
password:@"bar"
persistence:NSURLCredentialPersistencePermanent];
NSURLProtectionSpace *loginProtectionSpace = [[NSURLProtectionSpace alloc] initWithHost:@"foo.com"
port:8000
protocol:@"http"
realm:nil
authenticationMethod:NSURLAuthenticationMethodBasic];
[[NSURLCredentialStorage sharedCredentialStorage] setDefaultCredential:loginCredential
forProtectionSpace:loginProtectionSpace];
[loginProtectionSpace release];
loginCommunicator = [[LearnCommunicator alloc] initWithMethod:@"login-foo"
credential:loginCredential];
При такой настройке все делегаты NSURLConnection правильно вызываются
- (BOOL)connectionShouldUseCredentialStorage:(NSURLConnection*)connection
{
NSLog(@"connectionShouldUseCredentialStorage user: %@",[userCredential user]);
return YES;
}
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
{
NSLog(@"canAuthenticateAgainstProtectionSpaceuser: %@",[userCredential user]);
return YES;
}
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
NSLog(@"didReceiveAuthenticationChallenge previousFailureCount: %i",[challenge previousFailureCount]);
if ([challenge previousFailureCount] == 0)
{
NSLog(@"Challenging...");
[[challenge sender] useCredential:userCredential forAuthenticationChallenge:challenge];
}
else
{
NSLog(@"Username and password are incorrect");
[[challenge sender] cancelAuthenticationChallenge:challenge];
}
}
Любой вклад приветствуется!
Thx
РЕДАКТИРОВАТЬ ОБНОВЛЕНИЕ 01 Это, кажется, известная проблема, которая уже была подана как отчет об ошибке - давно - но не была решена. NSURLConnection, похоже, не поддерживает заголовок «Expect: 100-continue», что, честно говоря, является серьезным недостатком. Я работал над этой проблемой часами, чтобы узнать, что мне придется все переделывать. Подробную информацию смотрите в отчете об ошибке: http://openradar.appspot.com/5188833
РЕДАКТИРОВАТЬ ОБНОВЛЕНИЕ 02 Мой текущий обходной путь для этой проблемы - просто выполнить аутентификацию прямо перед тем, как перейти к огромному HTTP POST с данными фильма. Поскольку мне нужно также загрузить какой-нибудь незначительный XML-файл, я буду использовать его предварительную аутентификацию для загрузки фильма. Это все еще кажется мне уродливым, но я должен все делать ... Любой вклад / ноу-хау по этой теме все еще приветствуется.