NSURLCredentialPersistencePermanent не кажется постоянным? - PullRequest
2 голосов
/ 06 июля 2011

Я пытался решить это в течение некоторого времени, но безуспешно. Такие вопросы, как , этот здесь или вопросы использования аутентификации 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-файл, я буду использовать его предварительную аутентификацию для загрузки фильма. Это все еще кажется мне уродливым, но я должен все делать ... Любой вклад / ноу-хау по этой теме все еще приветствуется.

...