Несколько заголовков HTTP-авторизации?

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

GET /presence/alice HTTP/1.1 
Host: server.example.com
Authorization: Bearer mF_9.B5f-4.1JqM
Authorization: Basic YXNkZnNhZGZzYWRmOlZLdDVOMVhk

Я не вижу причин, по которым это не должно быть возможно, просто хотел проверить его с сообществом, чтобы быть уверенным.

Ответ 1

Это должно быть возможно, вам просто нужно добавить запятую между значениями поля, например:

GET /presence/alice HTTP/1.1 
Host: server.example.com
Authorization: Bearer mF_9.B5f-4.1JqM, Basic YXNkZnNhZGZzYWRmOlZLdDVOMVhk

Это определено в RFC7230, раздел 3.2.2, Порядок полей:

Отправитель НЕ ДОЛЖЕН генерировать несколько полей заголовка с одним и тем же именем поля в сообщении, если только все значение поля для этого поля заголовка не определено как список, разделенный запятыми [т.е. # (значения)], или поле заголовка не является известное исключение (как отмечено ниже).

Получатель МОЖЕТ объединить несколько полей заголовка с одним и тем же именем поля в одну пару "field-name: field-value", не изменяя семантику сообщения, добавляя каждое последующее значение поля в объединенное значение поля по порядку, разделяя их запятая. Порядок, в котором принимаются поля заголовка с одинаковым именем поля, имеет значение для интерпретации значения объединенного поля; прокси НЕ ДОЛЖЕН изменять порядок значений этих полей при пересылке сообщения.

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

Ответ 3

У меня был похожий вопрос. Кажется, это довольно распространенная проблема (ссылка на вопрос). В итоге я изменил заголовок авторизации для токена на предъявителя на нестандартный, такой как

X-Auth: Носитель mF_9.B5f-4.1JqM

Таким образом, это просто еще один HTTP-заголовок, и базовая авторизация http пройдет. Если вы разрабатываете свой собственный API, это не должно быть проблемой.

Некоторые дальнейшие исследования

Основываясь на RFC 2617, вот несколько интересных деталей.

Пользовательский агент ДОЛЖЕН выбрать использование одной из проблем с самой мощной схемой аутентификации, которую он понимает, и запрашивать учетные данные у пользователя на основе этой задачи.

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

Ответ 4

У меня та же проблема, пытаюсь передать два заголовка авторизации в запросе.

Наша установка следующая:

  • у нас есть защищенный ресурс (авторизованный через OAuth2), работающий внутри MS IIS (который также имеет уровень авторизации NTLM вокруг него)

  • чтобы получить доступ к защищенному ресурсу внутри IIS, нам нужно пройти ОБА авторизацию NTLM и авторизацию OAuth2

  • для этого я попытался создать заголовок авторизации, передавая оба значения заголовка через запятую

ех. Авторизация: NTLM YYYY, Носитель XXXX

Это не работает. Мы получаем 400 плохих запросов.

Знаете ли вы, как этого можно достичь (передавая несколько заголовков авторизации)?

Или вы можете предложить какой-нибудь обходной путь для прохождения обеих авторизаций (NTLM и OAuth2)?

Заранее спасибо Джон

Ответ 5

Можно иметь несколько заголовков авторизации, я столкнулся с той же проблемой при интеграции API, который принимает несколько авторизаций.

Вот пример React js для вызова API, который принимает несколько токенов авторизации.

axios.get(Constants.API+Constants.GET_USER,  {  headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
"Authorization": Constants.AUTH_Element + ',' + Constants.AUTH_ORG + ','+ 
Constants.AUTH_USER
}})
.then(function (response) {
    // handle success
    console.log(response);
})
.catch(function (error) {
    // handle error
    console.log(error);
})
.finally(function () {
    // always executed
});