2016-05-06 6 views
3

Я работаю над RESTful API, который включает стороннюю интеграцию. Мы используем OAuth с потоком кода авторизации для аутентификации против третьей стороны. Пользователь должен войти в нашу службу, а затем дополнительно к третьей стороне, чтобы наше приложение могло получить доступ к третьей стороне.HTTP API: сообщение о необходимости аутентификации третьей стороне

Некоторые из наших ресурсов требуют взаимодействия с третьей стороной (например, GET /third-party-userpic). Если пользователь уже зарегистрировался в этой службе, мы извлечем токен доступа из нашего хранилища данных и будем использовать его для получения изображения пользователя, просто!

Если у нас нет действительных учетных данных для этого пользователя для этой службы, мы не можем получить изображение пользователя. Это произойдет при первом использовании и может также произойти, если полномочия истекают или аннулируются. В этом случае мы хотим сообщить клиенту, что им нужно посетить URI авторизации и начать поток OAuth.

Мои коллеги и я разработке этого обсудили несколько возможностей, в том числе:

  • Возвращение 200 OK успеха с указанием того, что аутентификация требуется или разрешается в теле ответа так или иначе. Это неэлегантно и не распространяется на ресурсы разных типов контента, а также требует, чтобы клиент знал, когда он обращается к ресурсу, который может потребовать эту схему аутентификации.
  • Возврат 403 Forbidden вместе со ссылкой для аутентификации в заголовках или корпусе. Проблема в том, что это требует отличия от 403 Forbidden, сгенерированного из-за проблем с разрешениями, и не согласуется с тем, что мы хотим назвать 403.
  • Возврат 401 Unauthorized. У этой проблемы возникает та же проблема, что и клиент, чтобы ее разломать от 401, сгенерированной нашей платформой, когда пользователь не вошел в систему. Существует дополнительная проблема, что 401 Unauthorized является частью схемы аутентификации HTTP-запроса, но мы не реализуя поток ответных реакций здесь. Клиент никогда не касается учетных данных.
  • Создание нового кода состояния 4XX, позволяющего клиенту легко отделить это условие от других возможных сбоев. Это кажется самым чистым с технической точки зрения, но создание новых кодов статуса - это не то, что нам, вероятно, нужно делать!

ответ

1

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

В этом сценарии код ответа 2xx-класса практически не может быть и речи, поскольку действие не было успешным. Несмотря на то, что на стороне сервера отсутствует механизм, у клиента есть возможность исправить это (путем аутентификации через OAuth). Это исключает коды состояния класса 5xx, предлагая класс 4xx.

Как вы правильно заявили, 401 не совсем прав, поскольку этот код специфичен для запрашиваемого ресурса. От RFC 7235, section 3.1:

401 (Несанкционированное) код состояния указывает на то, что запрос не был применен, поскольку он не имеет действительные учетные данные проверки подлинности для целевого ресурса.

Однако целевой ресурс в вашем случае прекрасен; это внешняя услуга, вызывающая беспокойство. Кроме того, 401 заставляет вас задуматься о структуре аутентификации HTTP, которая представляет ряд практических вопросов.

Наиболее фитинга код состояния в этом диапазоне, действительно, 403. От RFC 7231, section 6.5.1:

403 (Запрещено) код состояния указывает на то, что сервер понял запрос, но отказывается разрешить его. Сервер, который хочет обнародовать, почему запрос был запрещен, может описать эту причину в полезной нагрузке ответа (если таковая имеется).

В то время как это может показаться на первый несвязанный, считают, что

[...] запрос может быть по причинам, не связанным с учетными данными запрещено.

RFC, также читает:

Клиент может повторить запрос с новыми или другими учетными данными.

Таким образом, этот код ослаблен тем, что он не является специфичным для запрашиваемого ресурса, но учитывает другие обстоятельства, препятствующие успешной работе. Это также самый код ответа, который вы получите, когда будете следовать блок-схеме на Choosing an HTTP Status Code — Stop Making It Hard.

0

Что https://tools.ietf.org/html/rfc6750 предлагает следующий:

  • клиента отвечает за запрос областей доступа, в основном ваш основной функциональности и функциональность сторонней должен быть описан как отдельные прицелы
  • , если клиент пытается получить доступ к ресурсу (в вашем случае некоторые функции сторонних разработчиков) без запроса доступа для него, сервер должен ответить 403 ответ lack_scope ошибка

insufficient_scope Запрос требует более высоких привилегий, чем предусмотренные токен доступа. Сервер ресурсов СЛЕДУЕТ ответить кодом статуса HTTP 403 (Запрещенный) и МОЖЕТ включать атрибут «scope» с областью, необходимой для доступа к защищенному ресурсу .

WWW-Authenticate: Bearer realm="myprotectedresource", 
    error="insufficient_scope", 
    error_description="Insufficient scope for this resource scopes", scope="SOME_SCOPE" 

Ниже схема последовательности операций авторизации от одного источника

+--------+        +---------------+ 
|  |--(A)- Authorization Request ->| Resource | 
|  |        |  Owner  | 
|  |<-(B)-- Authorization Grant ---|    | 
|  |        +---------------+ 
|  | 
|  |        +---------------+ 
|  |--(C)-- Authorization Grant -->| Authorization | 
| Client |        |  Server | 
|  |<-(D)----- Access Token -------|    | 
|  |        +---------------+ 
|  | 
|  |        +---------------+ 
|  |--(E)----- Access Token ------>| Resource | 
|  |        |  Server | 
|  |<-(F)--- Protected Resource ---|    | 
+--------+        +---------------+ 
+0

'401 Unauthorized' требует вызова WWW-Authenticate. Какой вызов я бы использовал? – coppro

+0

Я только что сделал быстрый поиск и придумал некоторые результаты, я буду обновлять ответ с дополнительной информацией с https://tools.ietf.org/html/rfc6750 – gevorg

+0

После прочтения более https://tools.ietf.org/html/rfc6750 Я думаю, что мой ответ глуп как ад, я постараюсь обобщить то, что я узнал в отредактированной версии. – gevorg

0

с указанием, что аутентификация требуется или разрешено в теле ответа каким-то образом

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

Если вы можете (и хотите), может быть что-то вроде этого:

HTTP/1.1 200 OK 
Date: Tue, 10 May 2016 01:08:07 GMT 
Content-Type: application/vnd.whatever+json 
Link: <https://third-party.example/authorize>; 
    rel="https://example.com/doc/#authorize-3rd-party" 
Warning: 299 - "part of the content is missing; authorize with third party" 

...content with only the pic missing... 

Если вы не можете (или не хотите), то 424 (Failed Dependency), 403 (Forbidden) (но смотри комментарии), и 400 (Bad Request) все звучат, как будто они могут быть соответствующими кодами состояния. Однако коды состояния не являются решением каждой проблемы. Совершенно нормально уточнять их значение в полезной нагрузке ответа. Там даже новый стандарт для this- RFC 7807:

HTTP/1.1 400 Bad Request 
Date: Tue, 10 May 2016 01:08:07 GMT 
Content-Type: application/problem+json 

{ 
    "type": "https://example.com/doc/#authorize-3rd-party", 
    "title": "You need to authorize with a third party for this.", 
    "authorizeAt": "https://third-party.example/authorize" 
} 

Вы очень правы в своих опасений по поводу 401 (Несанкционированное) и изобретает свой собственный код статуса.

+0

Я думаю, что добавление ссылки на соответствующую часть RFC не помешает: https://tools.ietf.org/html/rfc7231#section-6.5.3 – DaSourcerer

+0

@DaSourcerer На самом деле, я перечитал спецификацию и понял что 403 здесь не так. В нем говорится, что «отказывается авторизовать его», также «сервер считает [полномочия] недостаточными для предоставления доступа». Я изменил свой ответ. –

+0

Что? Нет, ты был прав! «Клиент МОЖЕТ повторить запрос с новыми или разными учетными данными. Однако запрос может быть запрещен по причинам, не связанным с учетными данными». Это вполне адекватно. – DaSourcerer