Статьи

Защита веб-приложений с использованием PKCE с помощью Spring Boot

Технология имеет способ обновления быстрее, чем стандарты безопасности. OAuth 2.0 — это новейший и лучший стандарт для современных приложений, но ему уже восемь лет! Его участники работают над следующей версией, пока мы говорим, и тем временем периодически выпускают «руководство», чтобы помочь разработчикам использовать OAuth 2.0 с новыми технологиями.

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

В этом руководстве основное внимание будет уделено наилучшим текущим методам обеспечения безопасности OAuth 2.0, а также будут рассмотрены практические последствия, которые имеет руководство для Spring Boot с приложениями Spring Security.

Сначала давайте выясним отношения между OAuth 2.0 и OpenID Connect. OAuth 2.0 для делегированной авторизации, а OpenID Connect для идентификации и находится поверх OAuth 2.0. Давайте посмотрим на эти два стандарта и почему они важны.

Трехминутный обзор OpenID Connect и OAuth 2.0

В начале были разрозненные сайты, которые не общались друг с другом, и все были грустными.

Такие сайты, как Yelp, начали получать доступ к контактной информации, которая была у вас в контактах Google. Итак, Yelp, естественно, собрал ваше имя пользователя и пароль Google, чтобы он мог получить доступ к вашим контактам. Вы дали Yelp свое разрешение, так что все было хорошо, да? Нет! С вашим именем пользователя и паролем Yelp может получить доступ к вашей электронной почте, вашим документам — всему, что у вас было в Google — не только вашим контактам. И что еще хуже, Yelp пришлось хранить ваш пароль таким образом, чтобы он мог использовать его в виде открытого текста, и не было стандартного способа отозвать ваше согласие на Yelp для доступа к вашей учетной записи Google.

Нам нужна была структура авторизации, которая позволяла бы вам предоставлять доступ к определенной информации без вашего пароля. Кий OAuth.

Используйте OAuth 2.0 для делегированной авторизации

Три ревизии спустя, мы находимся в OAuth 2.0 (до него было 1.0 и 1.0a) и все в порядке с миром. Теперь приложение, такое как Yelp (клиентское приложение), может запросить токен доступа у такой службы, как Google (сервер авторизации). Вы (владелец ресурса) входите в Google со своими учетными данными и даете свое согласие на Yelp для доступа к вашим контактам (и только вашим контактам). Получив токен доступа, Yelp запрашивает API контактов Google (сервер ресурсов) и получает ваши контакты. Yelp никогда не видит ваш пароль и никогда не имеет доступа ни к чему большему, чем вы согласились. И вы можете отозвать свое согласие в любое время.

Используйте OpenID Connect для идентификации

В этом новом мире согласия и авторизации не хватало только одного: идентичности. Cue OpenID Connect. OIDC — это тонкий слой поверх OAuth 2.0, который представляет токен нового типа: токен идентификации. В этих криптографически подписанных токенах в формате JWT содержится информация об аутентифицированном пользователе. Это открыло дверь на новый уровень взаимодействия и единого входа.

OAuth (и, соответственно, OIDC) используют несколько определенных потоков для управления взаимодействиями между клиентским приложением, сервером авторизации и сервером ресурсов. В этом посте я остановлюсь на потоке кода авторизации. Этот поток предназначен для запуска из вашего браузера и выглядит так:

  1. Yelp хочет получить доступ к вашим контактам. Он представляет собой кнопку, чтобы связать ваши контакты Google.
  2. Когда вы нажимаете кнопку, вы перенаправляетесь в Google, где вы входите под своим именем пользователя и паролем (если вы еще не вошли в систему).
  3. Google показывает вам экран, сообщающий, что Yelp хотел бы получить доступ только для чтения к вашим контактам.
  4. Как только вы дадите свое согласие, Google перенаправит обратно в Yelp через ваш браузер временный код (называемый кодом авторизации).
  5. Используя этот код, Yelp связывается с Google, чтобы обменять его на токен доступа
  6. Google проверяет код и, если все проверено, выдает токен доступа с ограниченными возможностями (доступ только для чтения к вашим контактам) для Yelp
  7. Затем Yelp представляет токен доступа в API контактов Google.
  8. API контактов Google проверяет токен и, если запрос соответствует возможностям, указанным токеном, возвращает ваш список контактов в Yelp

Использование конфиденциальных клиентов против публичных клиентов

Конфиденциальные клиенты работают на сервере и находятся под полным контролем компании, создавшей приложение. Spring Boot, .NET и Node.js являются примерами конфиденциальных приложений клиентского типа. Поскольку они запускаются на серверах и, как правило, находятся за брандмауэром с другими средствами защиты, можно безопасно настроить секретный клиент с секретом. В OAuth 2.0 это называется Client Secret. Сервер авторизации выдает и приложение, Client Idи a Client Secretдля использования в приложении, и именно так приложение аутентифицируется на сервере авторизации.

Общедоступные клиенты работают в средах, которые не могут контролироваться такими организациями, как компания. Существуют такие приложения, как одностраничные приложения (SPA) или мобильные или нативные приложения. Если в компании много пользователей, вполне вероятно, что какой-то процент этих пользователей скомпрометировал компьютеры или браузеры. У компании нет возможности это контролировать. Хранить секреты в этих типах приложений небезопасно, поскольку их можно проверять и декомпилировать. Чтобы воспользоваться преимуществами потока кода авторизации в общедоступном клиенте, используется расширение, называемое ключом проверки для обмена кодами (PKCE).

Изначально PKCE был разработан для повышения безопасности мобильных и нативных приложений, использующих OAuth 2.0. Недавно его использование было распространено на основанные на браузере приложения Singe-Page. Теперь PKCE рекомендуется даже для конфиденциальных клиентов.

Изучая раздел « Предоставление кода авторизации » в документе с рекомендациями по обеспечению безопасности, в нем говорится:

Клиенты, использующие тип разрешения авторизации, ДОЛЖНЫ использовать PKCE [RFC7636], чтобы (с помощью сервера авторизации) обнаруживать и предотвращать попытки внедрения (повторного воспроизведения) кодов авторизации в ответ авторизации.

Таким образом, использование PKCE имеет преимущество в безопасности даже с конфиденциальными клиентами, которые уже аутентифицируют себя с помощью секрета клиента.

Хотя это и не завершено, похоже, что следующая версия OAuth упростит стандарт и потребует использования PKCE во всех потоках, в которых участвует конечный пользователь (за пределами потока устройств ).

Последняя версия Spring Security (на момент написания статьи 5.2.1) изначально поддерживает OAuth 2.0 и OpenID Connect. Он поддерживает PKCE для публичных клиентов. Он пока не поддерживает PKCE для конфиденциальных клиентов. Есть запрос на удаление (написанный моим коллегой Брайаном Демерсом), который, как ожидается, будет включен в следующий выпуск. Тем не менее, Spring Security настолько хорошо написан и модульный, что сегодня легко подключиться к PKCE с конфиденциальным клиентом, чтобы воспользоваться преимуществами рекомендуемых лучших методов обеспечения безопасности.

Spring Star Boot Starter от Okta позволяет легко начать работу.

Начните с весеннего загрузчика Okta Starter

Вы можете найти полный исходный код этого поста здесь или перейти к start.spring.io, чтобы быстро создать приложение Spring Boot со всем необходимым для конфиденциального клиента. Единственные стартеры, которые вам нужны: Spring Web, Okta и Thymeleaf . Okta автоматически добавляет Spring Security. Thymeleaf используется для HTML-шаблонов. Ядро вашего pom.xmlдолжно выглядеть примерно так:


XML