Страницы

Поиск по вопросам

воскресенье, 22 декабря 2019 г.

JavaScript Application и авторизация через OAuth 2

#php #javascript #angularjs #oauth2


Дано:


Основной сайт (PHP+HTML) с поднятым OAuth 2 сервером
Доверенное приложение на этом же домене на Angular-е (100% javascript)


Задача:


Авторизация пользователей в приложении через собственный OAuth сервер (точнее нужен
токен для доступа к апи)
"Запомнить меня" (каждый раз тыкать кнопку и делать кучку редиректов не вариант)


Размышления:

Сама спецификация предусматривает для таких случаев Implicit Grant, но как реализовать
"запомнить" я так и не придумал ибо срок жизни токена ограничен, а получить новый можно
только через редиректы => оно неюзабельно.

Кроме того, например, вон там рассказывается что оно не безопасно и дана гениальная
идея использовать proxy и шифрованные кукисы для скрытия токенов (refresh_token получается
недоступен в js, но сохраняется в кукисах и может потом использоваться повторно) -
однако, я так и не понял что помешает использовать этот proxy напрямую? (имхо, бессмысленное
усложнение, возможно, ошибаюсь?) 

Следующей после после proxy была идея забить на спецификацию и использовать Authorisation
Code Grant с открытым client_secret - благодаря наличию refresh_token-а можно будет
получать новые токены и оставаться авторизованным. НО этот вариант по сути мало чем
отличается от Implicit Grant с "вечным" токеном + из-за большего количества действий
реализация получается немного сложнее.

Решение?

В итоге после прочтения тонны всяких статей на тему js + oauth и размышлений о том
как же оно всё криво изложенных выше остановился на следующем варианте: используя Client
Credentials Grant выполняем ajax POST на основной сайт и если пользователь там авторизован
("там" оно определяется по cookies) и ранее уже авторизовал приложение, то сразу возвращаем
токен (это и будет "запомнить меня"), если нет, то получаем первый токен через Implicit
Grant. Естественно это всё только при https, POST, X-Frame-Options: DENY и всё на одном
домене. Вроде бы оно не сильно дыряво получается? 



В общем то, хотелось бы услышать критику или предложите какой-нибудь другой вариант,
себе уже всю голову сломал :(
    


Ответы

Ответ 1



Вы, ровно как и Алекс Билби сильно преувеличиваете опасность авторизации клиентских приложений в OAuth2. Естественно, в фронтенде публичного веб-приложения не стоит организовывать получение прав через Resource Owner Password Credentials(когда OAuth-серверу для получения токена передаётся id приложения + логин/пароль пользователя). Не стоит использовать и Client Credentials(OAuth-серверу передаётся только id приложения, а авторизация происходит с использованием внешних систем - например через NTLM-хеш, либо через HTTP-basic-авторизацию). Впрочем, оба этих способа очень специфичны, и абсолютное большинство OAuth-серверов их просто-напросто не поддерживают... Для авторизации остаются только Explicit(Authorization Code) и Implicit. Explicit требует наличия веб-сервера. При этом access token клиенту не передаётся - клиентской стороне возвращается "статус" и "код авторизации", тот передаёт серверу приложения, а он используя код авторизации получает от OAuth-сервера токен доступа. Дополнительно(но не всегда обязательно) при получении токена доступа серверу приложения требуется отправить "client secret" - специальный код/пароль, по которому определяется подлинность вашего приложения, и без указания которого нельзя получить токен доступа. Implict не требует наличия веб-сервера, при этом токен доступа возвращается в url. И естественно "client secret" в этом случае не используется - OAuth-серверу отправляется только id приложение, которое собственно по определению не является секретной информацией(любой может просто скопировать его из url авторизации, даже при explicit-авторизации). Злоумышленник потенциально может украсть как токен доступа при Implicit авторизации, так и авторизационные cookies вашего сайта. Основным каналом утечки при этом являются XSS-уязвимости на вашем сайте, либо вредоносное ПО на компьютере пользователя. Что злоумышленник получит в случае кражи токена доступа/cookies? Для практически всё! И не важно, что применялась Explicit-авторизация и вы проксировали запросы - всю необходимую информацию он получит через ваш сайт. Основное преимущество "проксирования" состоит в том, что иногда поставщики OAuth-ресурсов создают чересчур широкие scope, включающие заведомо больший функционал, нежели необходимо вашему приложению(несмотря на спецификацию, требующую минимальность) - в этом случае вы можете отрезать доступ к нежелательным ресурсам на уровне вашего бекенда. Но и минус тоже есть - при Explicit-авторизации, в случае взлома вашего сервера, злоумышленник получит из хранилища токены доступа сразу всех пользователей приложения. В случае же Implict-авторизации, взломав ваш сервер, злоумышленник токены доступа пользователей сразу не получит(ему придется предваритально модифицировать код фронтенда, да выдирать сохраненные на клиентской стороне токены).

Комментариев нет:

Отправить комментарий