Защита облачных приложений с помощью OAuth 2.0 и OpenID Connect
Полное руководство по защите ваших облачных приложений с помощью OAuth 2.0 и OpenID Connect, а также о том, как предложить отличный пользовательский опыт с аутентификацией и авторизацией.
Введение
Облачные приложения - это тренд в наши дни. Хотя тип приложения может различаться (веб, мобильное, настольное и т.д.), они все имеют облачную серверную часть, которая предоставляет услуги, такие как хранение, вычисления и базы данных. Большинство из этих приложений необходимо аутентифицировать пользователей и авторизовать их для доступа к определённым ресурсам.
Хотя собственные механизмы аутентификации и авторизации возможны, безопасность стала одной из главных забот при разработке облачных приложений. К счастью, в нашей индустрии существуют проверенные стандарты, такие как OAuth 2.0 и OpenID Connect, которые помогают нам внедрять безопасную аутентификацию и авторизацию.
В этой статье предполагается следующее:
- У вас есть базовое понимание разработки приложений (веб, мобильные или любого другого типа).
- Вы слышали о концепциях аутентификации и авторизации.
- Вы слышали о OAuth 2.0 и OpenID Connect.
Да, "слышали" достаточно для пунктов 2 и 3. В этой статье будут использованы примеры из реального мира для пояснения концепций и иллюстрации процесса с помощью диаграмм. Давайте начнем!
OAuth 2.0 vs. OpenID Connect
Если вы знакомы с OAuth 2.0 и OpenID Connect, вы можете продолжать чтение, потому что мы рассмотрим несколько примеров из реальной жизни в этом разделе; если вы новичок в этих стандартах, продолжайте чтение - мы представим их простым способом.
OAuth 2.0
OAuth 2.0 представляет собой рамки авторизации, которые позволяют приложению получить ограниченный доступ к защищённым ресурсам на другом приложении от имени пользователя или самого приложения. Большинство популярных сервисов, таких как Google, Facebook и GitHub, используют OAuth 2.0 для социальной авторизации (например, "Войти с Google").
Например, у вас есть веб-приложение MyApp, которое хочет получить доступ к Google Drive пользователя. Вместо того чтобы просить пользователя предоставить учетные данные Google Drive, MyApp может использовать OAuth 2.0, чтобы запросить доступ к Google Drive от имени пользователя. Вот упрощенный поток:
В этом потоке MyApp никогда не видит учетные данные Google Drive пользователя. Вместо этого, оно получает токен доступа от Google, который позволяет ему получать доступ к Google Drive от имени пользователя.
В терминах OAuth 2.0: MyApp является клиентом, Google является одновременно сервером авторизации и сервером ресурсов для простоты. В реальном мире мы часто имеем отдельные серверы авторизации и ресурса, чтобы предоставить опыт единого входа (SSO). Например, Google является сервером авторизации и может иметь несколько серверов ресурсов, таких как Google Drive, Gmail и YouTube.
Заметьте, что на самом деле поток авторизации сложнее, чем это. У OAuth 2.0 есть различные типы предоставления, области действия и другие концепции, которые необходимо знать. Оставим это в стороне и перейдём к OpenID Connect.
OpenID Connect (OIDC)
OAuth 2.0 отлично подходит для авторизации, но, возможно, вы заметили, что в нём нет способа идентифицировать пользователя (то есть аутентификации). OpenID Connect является слоем идентификации поверх OAuth 2.0, который добавляет возможности аутентификации.
В приведенном выше примере MyApp должна знать, кто является пользователем до начала потока авторизации. Обратите внимание, что здесь участвуют два пользователя: пользователь MyApp и пользователь Google Drive. В данном случае MyApp должна идентифицировать пользователя своего собственного приложения.
Посмотрим простой пример, предположим, что пользователи могут войти в MyApp, используя имя пользователя и пароль:
Поскольку мы аутентифицируем пользователя нашего собственного приложения, обычно нет необходимости запрашивать разрешения, как это делал Google в потоке OAuth 2.0. Между тем, нам нужно что-то, что может идентифицировать пользователя. OpenID Connect вводит концепции, такие как ID токен и точка доступа userinfo, чтобы помочь нам в этом.
Вы можете заметить, что поставщик идентификации (IdP) является новым отдельным участником в потоке. Он такой же, как и сервер авторизации в OAuth 2.0, но для лучшей ясности мы используем термин "IdP", чтобы показать, что он отвечает за аутентификацию пользователей и управление идентичностью.
Когда ваш бизнес растет, у вас может быть несколько приложений, использующих одну и ту же базу данных пользователей. Как и в случае OAuth 2.0, OpenID Connect позволяет вам иметь единственный сервер авторизации, который может аутентифицировать пользователей для нескольких приложений. Если пользователь уже вошел в одно приложение, ему не нужно повторно вводить свои учетные данные, когда другое приложение перенаправляет его на IdP. Поток может выполняться автоматически без взаимодействия с пользователем. Это называется единым входом (SSO).
Опять же, это очень упрощенный поток, и под капотом скрыто множество деталей. Для начала, давайте перейдем в следующий раздел, чтобы не перегружать информацией.
Типы приложений
В предыдущем разделе мы использовали в качестве примеров веб-приложения, в то время как мир более разнообразен. Для поставщика идентификаций точный язык программирования, фреймворк или платформа, которые вы используете, на самом деле не важны. На практике одним из заметных различий является то, является ли приложение публичным клиентом или частным (доверенным) клиентом:
- Публичный клиент: Клиент, который не может сохранить свои учетные данные конфиденциальными, что означает, что владелец ресурса (пользователь) может получить к ним доступ. Например, веб-приложение, работающее в браузере (например, одностраничное приложение).
- Частный клиент: Клие нт, который имеет возможность сохранять свои учетные данные конфиденциальными, не раскрывая их пользователям (владелцам ресурса). Например, веб-приложение, работающее на сервере (например, серверное веб-приложение) или служба API.
С учетом этого давайте посмотрим, как OAuth 2.0 и OpenID Connect могут быть использованы в различных типах приложений.
"Приложение" и "клиент" можно использовать взаимозаменяемо в контексте этой статьи.
Веб-приложения, работающие на сервере
Приложение работает на сервере и предоставляет HTML-страницы пользователям. Многие популярные веб-фреймворки, такие как Express.js, Django и Ruby on Rails, относятся к этой категории; и фреймворки backend-for-frontend (BFF) типа Next.js и Nuxt.js также включены. Эти приложения обладают следующими характеристиками:
- Поскольку сервер допускает только частный доступ (публичные пользователи не могут увидеть код сервера или учетные данные), он считается частным клиентом.
- Общий поток аутентификации пользователей такой же, к ак тот, который мы обсудили в разделе "OpenID Connect".
- Приложение может использовать ID токен, выданный поставщиком идентификаций (то есть, поставщиком OpenID Connect), для идентификации пользователя и отображения контента, специфичного для пользователя.
- Чтобы сохранить приложение в безопасности, оно обычно использует поток кода авторизации для аутентификации пользователей и получения токенов.
Между тем, приложению может понадобиться доступ к другим внутренним службам API в архитектуре микросервисов; или это может быть монолитное приложение, которому необходим контроль доступа к различным частям приложения. Мы обсудим это в разделе "Защита вашего API".
Одностраничные приложения (SPA)
Приложение работает в браузере пользователя и взаимодействует с сервером через API. React, Angular и Vue.js - популярные фреймворки для создания SPA. Эти приложения обладают следующими характеристиками:
- Поскольку код приложения виден общественности, оно считается публичным клиентом.
- Общий поток аутентификации пользователей такой же, как тот, который мы обсудили в разделе "OpenID Connect".
- Приложение может использовать ID токен, выданный поставщиком идентификаций (то есть, поставщиком OpenID Connect), для идентификации пользователя и отображения контента, специфичного для пользователя.
- Чтобы сохранить приложение в безопасности, оно обычно использует поток кода авторизации с PKCE (Proof Key for Code Exchange) для аутентификации пользователей и получения токенов.
Обычно SPA необходимо доступ к другим службам API для получения и обновления данных. Мы обсудим это в разделе "Защита вашего API".
Мобильные приложения
Приложение работает на мобильном устройстве (iOS, Android и т.д.) и взаимодействует с сервером через API. В большинстве случаев эти приложения обладают теми же характеристиками, что и SPA.
Машина-к-машине (M2M) приложения
Машина-к-машине приложения - это клие нты, которые работают на сервере (машине) и взаимодействуют с другими серверами. Эти приложения обладают следующими характеристиками:
- Как и веб-приложения, работающие на сервере, M2M приложения являются частными клиентами.
- Приложению может не потребоваться идентификация пользователя; вместо этого, оно должно аутентифицироваться для доступа к другим службам.
- Приложение может использовать токен доступа, выданный поставщиком идентификаций (то есть, поставщиком OAuth 2.0), для доступа к другим службам.
- Чтобы сохранить приложение в безопасности, оно обычно использует поток с учетными данными клиента для получения токенов доступа.
При доступе к другим службам приложению может потребоваться предоставить токен доступа в заголовке запроса. Мы обсудим это в разделе "Защита вашего API".
Приложения, работающие на устройствах IoT
Приложение работает на устройстве IoT (например, устройства умного дома, носимые устройства и т.д.) и взаимодействует с сервером через API. Эти приложения обладают следующими характеристиками:
- В зависимости от возможностей устройства, оно может быть публичным или частным клиентом.
- Общий поток аутентификации может быть отличным от того, что мы обсудили в разделе "OpenID Connect", в зависимости от возможностей устройства. Например, некоторые устройства могут не иметь экрана для ввода пользователем своих учетных данных.
- Если устройству не нужно идентифицировать пользователя, оно может не нуждаться в использовании ID токенов или точек доступа userinfo; вместо этого, оно может рассматриваться как машина-к-машине (M2M) приложение.
- Чтобы сохранить приложение в безопасности, оно может использовать поток кода авторизации с PKCE (Proof Key for Code Exchange) для аутентификации пользователей и получения токенов или поток с учетными данными клиента для получения токенов доступа.
При взаимодействии с сервером устройству может потребоваться предоставить токен доступа в заголовке запроса. Мы обсудим это в разделе "Защита вашего API".