Аутентификация клиентского приложения для REST API с использованием CORS с локальной стратегией
Проблема:
Обслуживание защищенного API для клиентского приложения с использованием только локальной стратегии проверки подлинности.
Красные стрелки являются частью пробела знаний.
![enter image description here]()
Контекст:
Это --- client.example.com
делает POST до api.example.com/login
, где при успехе client.example.com
может получить доступ к сервису GET, например api.example.com/secret
.
Идея!
Импликация OAuth 2.0 с гибридным типом гранта, сидящим перед API.
Почему гибрид?
-
Это не будет Implicit Grant Flow
aka Client-Side Web Applications Flow
, потому что перенаправление на сервер API также не допускается. (т.е.) "Доступно ли вам так или иначе доступ к вашим данным?"
-
Это не будет Resource Owner Password Flow
, потому что вместе с запросом передаются идентификатор клиента и клиентский секрет, поэтому предполагается, что клиентское приложение является серверным.
ОК... так что о чем-то другом?
Что делать, если мы использовали токен CRSF при загрузке страницы клиентского приложения, а POST с учетными данными пользователя тоже OAuth 2.0 аутентификационной точки для обмена токеном доступа? После успешного входа в систему вы должны аутентифицировать каждый последующий запрос с помощью токена доступа и токена CRSF.
Хорошая библиотека Node.js OAuth 2.0, которую я нашел:
https://github.com/ammmir/node-oauth2-provider
Помогите мне!
Я не могу найти рабочий пример проверки подлинности, который решает эту проблему! Направьте меня в правильном направлении?
В конечном счете, цель здесь - слишком аутентифицировать приложение на стороне клиента для REST api, используя CORS с локальной стратегией --- то есть имя пользователя и пароль --- даже если вышеописанное соглашение невозможно.
Чтобы присвоить награду:
Это приложение для клиентской стороны, поэтому пусть остается модным.
Я ищу рабочий пример с использованием Node.js OAuth 2.0 семян выше для сервера API/Auth и фреймворка переднего конца, например Angular.js или Backbone.js, чтобы делать запросы.
Пример должен соответствовать контексту, описанному выше.
Ответы
Ответ 1
Я работаю над приложением с довольно подобной архитектурой, хотя сервисами являются .NET Web API, а не Node, и мы используем DotNetOpenAuth для поставщика OAuth. Вместо гибридного подхода вы предполагаете, что мы делаем следующее:
- x.com обслуживает страницу входа в систему
- страница входа в систему POST возвращает учетные данные на x.com
- логика на стороне сервера на x.com объединяет client_id и client_secret с учетными данными для отправки запроса на токен (учетные данные пароля владельца ресурса, ве
упомянутый выше), получая как токен доступа, так и
Обновить токен
- токен обновления зашифрован в файл cookie, выпущенный x.com.
- оба файла cookie (с зашифрованным токеном обновления) и токен доступа затем отправляются в браузер
- клиентское приложение (angular в моем случае) теперь может использовать токен доступа для доступа к api.x.com для сервисов (похоже, вы хорошо знаете ограничения CORS... мы взломали версию angular $resource, чтобы облегчить это, но это было не так, потому что мы хотели использовать все HTTP-глаголы и поддерживать IE9)
- когда истекает токен доступа, клиентское приложение может запросить новый токен доступа с сайта x.com
- серверная сторона, x.com расшифровывает cookie, чтобы получить токен обновления и выдает другой вызов oauth для нового токена доступа
Это довольно высокий уровень, но, надеюсь, дает вам представление о том, как справиться с ситуацией. В моем случае, и он появляется в вашем, мы не хотели использовать состояние сеанса или базу данных для хранения токена обновления, но, очевидно, раскрытие этого браузером приводит к проблемам безопасности, поэтому важное значение имеет шифрование токена обновления (среди других параметров безопасности соображения), а использование файла cookie устраняет необходимость в состоянии сеанса или другом постоянном хранилище на x.com.
Ответ 2
Я построил этот пример, используя Node и PassportJS, чтобы показать, как аутентифицировать пользователей с помощью Facebook или локальной стратегии. Обе стороны находятся в разных доменах, как вы описали, и для этого требуется CORS.
GitHub: https://github.com/pablodenadai/Corsnection
Демо-версия: http://corsnection-client.herokuapp.com/
Ответ 3
Не будет ответа на приз. Только мои 2 цента:)
На моем веб-сервере
Я выполняю аутентификацию через вызов останова с логином/паролем с базовой аутентификацией по https. Этот вызов предоставляет ключ клиенту (одностраничное веб-приложение).
Затем каждый последующий вызов REST подписывается ключом. Сервер проверяет правильность сигнатуры и все еще происходит в https.
Этот механизм вполне используется. Я полагаю.
Я не вижу проблемы с перекрестным доменом. У меня есть один источник anf, если мне нужно что-то из другого источника, я бы использовал JSONP.
Я использую nginx как https- > http forwarder.
Не уверен, как он конкурирует с решением OAuth2.
Ответ 4
Я не могу обещать, что у меня есть время написать рабочий пример, но я могу показать вам 2 пути:)
Самая большая сделка - CORS. После решения этой проблемы легко использовать $http. Итак, первым и, вероятно, самым простым может быть настройка обратного прокси-сервера на веб-сервере x.com, который указывает на api.x.com. Я написал статью здесь
Второй подход лучше и создан именно для этой цели, для авторизации определенного домена для использования вашего ресурса. Это связано с немного кодированием на api.x.com, поэтому вам не нужно ничего менять в новых веб-приложениях, обслуживаемых в других доменах. Вам просто нужно разрешить запросы CORS в службе api.x.com.
- Создать таблицу в базе данных, где вы можете управлять списком разрешенных доменов.
- Добавить в эту таблицу запись "x.com"
- в api.x.com добавьте фильтр запроса/перехватчик, какой технический термин вы используете для метода, который должен быть вызван после обработки запроса, и добавьте ответ
Access-Control-Allow-Origin: x.com
, если запрос поступает с x.com(другими словами, проверьте значение соответствия заголовка запроса соответствует любому значению в таблице выше и помещает это значение в заголовок ответа Access-Control-Allow-Origin).
Вот и все:) После этого, если вы знаете, как использовать $http или jQuey.ajax вы сможете выполнить POST/PUT/DELETE/... любой запрос на api.x.com из любого разрешенного домена всего за несколько минут.
Ответ 5
Я очень похожую идею, используя веб-приложение vinilla js и проверку междоменной аутентификации на бэкэнд GAE или OpenID.
Веб-приложение запускается на CDN. Когда щелкните ссылку для входа в систему, он перейдет на соответствующий сервер регистрации и перенаправит обратно в веб-приложение (с токеном безопасности XSRF и только с файлом cookie HTTPS). Сервер регистрации принимает запрос перекрестного домена с учетными данными. Каждому запросу должен быть установлен токен XSRF (в заголовке). cookie устанавливается браузером. Поскольку это HTTP файл cookie, JS не может его прочитать. Техника очень безопасна.
После входа в систему вы можете получить безопасную оценку от сервера входа.
Для подробного описания вы можете найти здесь и с открытым исходным кодом repo здесь.