Используя Дайджест-аутентификацию HTTP на iPhone

У меня есть приложение, которое связывается с сервером, который использует Дайджест-аутентификацию HTTP.

Мне кажется, что управление 'сессией' в iPhone является довольно "черным квадратом" нам разработчики. Действительно ли это верно, что мы не видим, как дескрипторы платформы / сохраняют сеансы HTTP?

Если бы я просто тускл здесь, кто-то хотел бы объяснить, как, вероятно, обработать Дайджест-аутентификацию HTTP на iPhone?

Мои основные пробегают:

  • Выполните запрос к защищенному URL
  • Сервер отправляет 401
  • клиент создает и сохраняет учетные данные и пасует назад их к серверу
  • сервер проверяет учетные данные, завершает запрос, если проверено, отправляет еще 401 если нет.
  • выполните последующий запрос для обеспечения URL
  • авторизация запросов к серверу снова........

Это работает на единственные запросы, но если я выполняю дополнительные, последующие запросы, авторизация запросов к серверу снова. Сервер сохранил сессию для конкретного пользователя, но iPhone не выполняет запрос в рамках той же сессии по некоторым причинам... Поэтому сервер должен вывести объект аутентификации и создать новый каждый раз, когда клиент выполняет запрос к защищенному URL.

Я уверен, что это не корректное поведение.

Если мы смотрим на то, как браузер ведет себя в этой ситуации:

  • Браузер запрашивает данные от безопасного URL
  • сервер отправляет 401
  • браузер предлагает пользователю учетные данные, сохраняет их, передает их серверу
  • сервер проверяет, что учетные данные, возвращая данные, если проверено, отправляют еще 401 если нет.
  • последующие запросы, выполненные для обеспечения URL, не запрашиваются учетные данные, потому что браузер управляет сессией.

Я создаю NSURLCredential и сохраняю его в NSURLCrendtialStorage. Затем, когда приложение получает 'didReceiveAuthenticationChallenge', я получаю учетные данные от устройства хранения данных и пасую назад его, создавая учетные данные, если это не существует (по первому запросу).

Любая справка значительно ценилась бы.Спасибо.

7
задан Jasarien 8 September 2009 в 10:10
поделиться

2 ответа

Во-первых, следует забыть о сеансах HTTP, поскольку они не взаимодействуют с активными входами в систему с дайджест-аутентификацией (есть своего рода возможность получения информации о сеансе, но она другая).

Действительно, одна из основных причин использования Digest - не использовать сеансы только для поддержания состояния входа в систему. Сеансы тяжелые и ухудшают масштабируемость.

Я не могу точно сказать, в чем заключается ваша проблема, но я знаю, что нужно проверить в первую очередь, а именно: правильное использование устаревших и правильное создание одноразовых номеров.

Пользовательские агенты могут обрабатывать аутентификацию без запроса пользователя только в том случае, если их просят обработать один и тот же одноразовый номер, или в другом случае, к которому я вернусь позже (проще объяснить это в таком порядке).

Если в каждом запросе используется один и тот же одноразовый номер, то пользовательский агент продолжит использовать его вместе с «ha1» от пользователя / прохода для запроса последующих ресурсов. Это делается заранее, поэтому проблемы никогда не возникает.

Конечно, использование одного и того же одноразового номера вносит элемент небезопасности, поскольку атаки с повторением становятся тривиальными для любого, кто может перехватить трафик. Nonce придется менять на регулярной основе.

Следовательно, если вы получили запрос от пользовательского агента с недопустимым заголовком авторизации, но он недействителен, потому что одноразовый номер неверен (он использует просроченный), тогда в вашем запросе укажите "stale = true" (по умолчанию false).Это информирует пользовательский агент о том, что ваша причина отклонения заключается в том, что одноразовый номер устарел (конечно, другая информация также может быть неверной, но это не имеет значения, поскольку вы не собираетесь позволять ей играть в любом случае).

При получении такого stale = true пользовательский агент будет знать, что он не авторизован, но вместо того, чтобы повторно запрашивать пользователя (или генерировать исключение, если это компонент без пользовательского интерфейса), попытается повторить старые критерии с новыми одноразовый.

Я не могу сказать, влияет ли что-либо из этого на вас, но то, как определяются и сигнализируются одноразовые номера и устаревшие данные, безусловно, является первым, на что я обращаю внимание.

3
ответ дан 7 December 2019 в 14:34
поделиться

Я написал приложение для iPhone с HTTP-аутентификацией и испытал то, что вы описываете. (Мое приложение использует базовую аутентификацию вместо дайджест-аутентификации, но здесь это не имеет большого значения.)

Причина проблемы на стороне iPhone. Сервер должен ответить 401, если iPhone не отправляет учетные данные в заголовке HTTP-запроса. И на самом деле это не так, хотя это может быть легко, когда учетные данные хранятся в хранилище учетных данных.

Это странное поведение сильно сказалось на скорости работы приложения, так как каждый запрос вызывал два обращения к серверу вместо одного (первый со статусом 401, второй со статусом 200).

Я решил эту проблему, вручную установив учетные данные в заголовке HTTP-запроса:

NSString* credentials = [NSString stringWithFormat: @"%@:%@", usr, pwd];
const char* credentialsChars = [credentials cStringUsingEncoding: NSUTF8StringEncoding];
credentials = [CommunicationUtil stringBase64WithData: (const UInt8*) credentialsChars length: strlen(credentialsChars)];
NSString* authorizationHeader = [NSString stringWithFormat: @"Basic %@", credentials];

NSMutableURLRequest* request =
    [[NSMutableURLRequest alloc] initWithURL: url 
        cachePolicy: NSURLRequestReloadIgnoringLocalCacheData
        timeoutInterval: 15];

    [request setValue: authorizationHeader forHTTPHeaderField: @"Authorization"];

Теперь мое приложение работает очень плавно и быстро реагирует.

Решение для дайджест-аутентификации будет выглядеть несколько иначе. Но вы поняли идею.

1
ответ дан 7 December 2019 в 14:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: