Я читал различные потоки авторизации 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, я хотел бы прочитать их, спасибо Вам за любую помощь.