OAuth & Authorization Grant Flow - отвечает ли браузер или серверная часть, которая обслуживает SPA, за обмен кода предоставления для токена доступа? - PullRequest
0 голосов
/ 06 июля 2019

Я читал различные потоки авторизации OAuth, чтобы лучше понять, как защитить мое приложение /, возможно, развернул свой собственный пример поставщика OAuth / OIDC / Single-Sign-On, чтобы понять некоторые абстракции, которые охватывают библиотеки Okta / Auth0.

Несмотря на то, что я понимаю общий поток запросов, мне очень трудно различить Client, Browser и Resource Server.

Я представляю себе традиционный SPA, который обслуживается тем же доменом и репозиторием, который содержит собственный SPA приложения. Итак, приложение Express / NodeJS, которое содержит конечные точки CRUD, а также может обслуживать приложение html / js для доступа к этим конечным точкам.

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

Чтобы войти в мое приложение, пользователь будет перенаправлен на страницу входа, обслуживаемую отдельным доменом провайдера аутентификации.

Насколько я понимаю, здесь неявного потока достаточно, после того как мой сервер аутентификации проверит учетные данные клиента, ответ 302, содержащий мой access_token в параметре URL-адреса хеш-функции, будет отправлен обратно в мое приложение.

https://my-app/callback
#access_token=ey123AsMhPw...
&expires_in=7200
&token_type=Bearer
&id_token=mA8s1#3...

Это подводит меня к моему первому вопросу:

Почему токен доступа отображается непосредственно в URI обратного вызова?

Ожидается, что мое приложение будет анализировать токен доступа по URL-адресу и сохранять его в хранилище сеансов, тогда как я думал, что рекомендуется всегда отправлять токен доступа в HTTPonly Secure Cookie

В этом случае токен обновления не отправляется. Но если я хочу реализовать единый вход, мне нужен идентификатор на основе cookie-файлов между клиентским браузером и доменом аутентификации, поэтому даже если я хочу использовать Implicit Flow для этого примера, я бы хотел иметь возможность войти со второго приложением и идентифицирует пользователя - но неявный поток не позволяет отправлять токен обновления, поэтому сервер проверки подлинности просто генерирует строку случайного идентификатора в виде файла cookie?

Должен ли я вместо этого использовать поток кода авторизации?

В соответствии с современными рекомендациями по обеспечению безопасности SPA с использованием кода авторизации PKCE

Опять же, клиент отправляется на страницу входа, обслуживаемую сторонним доменом аутентификации. Несколько идентификаторов должны быть отправлены, чтобы убедиться, что попытка входа в систему осуществляется из доверенного приложения. Сервер, который обслуживает SPA, также хранит client_id и client_secret в некотором скрытом исходном коде, таком как файл .env.

https://authorization-server.com/auth-login
?response_type=code
&client_id=CLIENT_ID
&redirect_uri=REDIRECT_URI
&scope=photos
&state=1234zyx

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

Do you wish to allow App 2 to access your data? Example App 1 will share your name and email address

В любом случае, если пользователь входит в систему или он разрешил использование данных своего исходного приложения, authorization code генерируется и сохраняется в Auth DB. Этот код также отправляется обратно клиенту в качестве перенаправления.

https://example-app.com/REDIRECT_URI
?code=abcdefg
&state=1234zyx

Это мой главный вопрос, КТО ТОЛЬКО использует эту информацию и отправляет запрос конечной точке /token на обмен кода разрешения на токен доступа? Это бэкэнд моего веб-приложения или интерфейс / браузер?

Я предполагаю, что это ДОЛЖЕН быть Бэкэнд, поскольку ответ приходит в виде простого JSON, а для конечной точки токена требуется СЕКРЕТ КЛИЕНТА Запрос токена

POST
https://authorization-server.com/token
?grant_type=authorization_code
&code=abcdefg
&redirect_uri=/you-are-now-logged-in/
&client_id=...
&client_secret=...

Ответ токена:

{
  "access_token":"MTQ0NjJkZmQ5OTM2NDE1ZTZjNGZmZjI3",
  "token_type":"bearer",
  "expires_in":3600,
  "refresh_token":"IwOGYzYTlmM2YxOTQ5MGE3YmNmMDFkNTVk",
  "scope":"create delete"
}

Как именно эта информация хранится и управляется бэкэндом веб-приложения?

Рекомендуется отправлять токены обратно как HTTPON SECURE COOKIES. Сервер проверки подлинности должен содержать все пользовательские разрешения и области, автономный JWT не нужно проверять по базе данных, все конечные точки API могут декодировать JWT через промежуточное программное обеспечение и напрямую разрешать чтение, чтобы решить, может ли данный пользователь выполнять различные охраняемые маршруты.

Но лучшие практики также говорят НИКОГДА НЕ ОТПРАВЛЯЙТЕ СВОЙ ЖУРНАЛ СЕРВЕРУ РЕСУРСА

Что если мое SPA / Web-приложение использует этот поток для запроса токена доступа для доступа к своим собственным конечным точкам? Ответ только что отправил обратно токен обновления. Я думал, что только стороны, которые могут иметь доступ к токену обновления, будут Клиент (Веб-браузер) и Сервер аутентификации (через cookie?)

Лучше ли полностью избегать отправки токена в виде файла cookie в веб-браузер, а сохранять токен обновления и токен доступа на бэкэнд-сервере веб-приложения как зашифрованную сессию?

Приношу свои извинения за длинный вопрос, любая помощь по любому из этих пунктов была бы признательна, и если есть какие-либо репозитории / исходный код, которые пытаются создать провайдер идентификации OICD / OAuth, я хотел бы прочитать их, спасибо Вам за любую помощь.

...