Что такое авторизация? | Энциклопедия «Касперского»

Что такое оauth2.0?

Разработку нового Auth мы решили начать с изучения доступных протоколов и технологий. Самый распространённый стандарт авторизации — фреймворк авторизации OAuth2.0. 

Стандарт был принят в 2022 году, и за 8 лет протокол меняли и дополняли. RFC стало настолько много, что авторы оригинального протокола решили написать OAuth 2.1, который объединит все текущие изменения по OAuth 2.0 в одном документе. Пока он на стадии черновика.

Актуальная версия OAuth описанна в RFC 6749. Именно его мы и разберем. 

OAuth 2.0 — это фреймворк авторизации.

Он описывает, как должно реализовываться взаимодействие между сервисами для обеспечения безопасной авторизации. Многие нюансы описаны достаточно подробно, например, flow взаимодействия узлов между собой, но некоторые отдаются на откуп конкретной реализации.

Особенности:

Разберёмся подробнее в особенностях.

Описание необходимых действий

Предположим, что в нашем приложении есть следующие роли пользователей:

Определим возможные действия с проектом:

(отмечу, что действия могут быть самыми различными, например редактировать только открытые проекты, просматривать только свои проекты и т.д. — сколько хватит фантазии и требования к авторизации в приложении).

Опишем это средствами фреймворка:

import com.exadel.easyabac.model.core.Action;

public enum ProjectAction implements Action {
    VIEW,
    UPDATE,
    CLOSE,
    DELETE
}

Здесь единственным условием является реализация интерфейса-маркера com.exadel.easyabac.model.core.Action. Все остальное в enum — на усмотрение разработчика.Сразу отмечу, что именно через данный enum удобно делать привязку к роли пользователя и (или) пермишенам пользователя, любым способом — можно статически, можно динамически.

Что такое grant?

Grant — это данные, которые представляют из себя успешную авторизацию клиента владельцем ресурса, используемые клиентом для получения access token.

Например, когда мы где-либо аутентифицируемся с помощью Google, перед глазами всплывает уведомление. В нём говорится, что такой-то сервис хочет получить доступ к данным о вас или к вашим ресурсам (выводятся запрашиваемые scope-token). Это уведомление называется «Consent Screen».

В момент, когда нажимаем «ОК», в базу данных попадает тот самый grant: записываются данные о том, что такой-то пользователь дал такие-то доступы такому-то сервису. Клиент получает какой-то идентификатор успешной аутентификации, например строку, которая ассоциируется с данными в базе данных.

Существует 4 1 способа получения grant — grant type:

Создание аннотаций для управления доступом

Создадим аннотацию-идентификатор проекта:

Создание валидатора для проверки прав

Остается добавить валидатор:

Ограничение доступа

Теперь, чтобы ограничить доступ к ресурсу остается расставить аннотации:

import com.exadel.easyabac.model.annotation.ProtectedResource;
import com.example.abac.Project;
import com.example.abac.model.ProjectAccess;
import com.example.abac.model.ProjectAction;
import com.example.abac.model.ProjectId;
import org.springframework.web.bind.annotation.*;

@RestController
@ProtectedResource
@RequestMapping("/project/{projectId}")
public class ProjectController {

    @GetMapping
    @ProjectAccess(ProjectAction.VIEW)
    public Project getProject(@ProjectId @PathVariable("projectId") Long projectId) {
        Project project = ...; // get project here
        return project;
    }

    @PostMapping
    @ProjectAccess({ProjectAction.VIEW, ProjectAction.UPDATE})
    public Project updateProject(@ProjectId @PathVariable("projectId") Long projectId) {
        Project project = ...; // update project here
        return project;
    }

    @PostMapping("/close")
    @ProjectAccess(ProjectAction.CLOSE)
    public Project updateProject(@ProjectId @PathVariable("projectId") Long projectId) {
        Project project = ...; // close project here
        return project;
    }

    @DeleteMapping
    @ProjectAccess(ProjectAction.DELETE)
    public Project updateProject(@ProjectId @PathVariable("projectId") Long projectId) {
        Project project = ...; // delete project here
        return project;
    }
}

@ProtectedResource аннотация используется для обозначения ресурсов, для которых нужна авторизации — в данном случае все instance-методы класса должны содержать как минимум одну @Access-based аннотацию, если это требования не выполняется — будет ошибки компиляции.

@PublicResource аннотация используется для обозначения метода который не требует авторизации, в том случае, если класс, содержащий метод помечен как @ProtectedResource

На этом, собственно, конфигурация и заканчивается. Сразу можно отметить что местом применения может быть не обязательно контроллер, это может быть любой класс (например сервис).

Реализация валидатора

Давайте рассмотрим более подробно как это работает. Фреймворк предоставляет каркас для построения архитектуры авторизации в приложении. Написание логики авторизации является задачей пользователя, это сделано для того, чтобы обеспечить достаточный уровень гибкости — обработка в приложениях может осуществляться по-разному.

Проверка прав выполняется в валидаторе, который должен реализовывать интерфейс EntityAccessValidator, а именно метод validate:

public void validate(ExecutionContext<Action> context);

ExecutionContext содержит необходимую информацию о требуемых правах доступа к ресурсу и мета-информацию о контексте вызова: context.getRequiredActions() вернет список Action, которые необходимо иметь пользователю.

Authorization code


Самый распространённый flow на данный момент. В основном используется для confidential клиентов, но с появлением дополнительной проверки с помощью PKCE, может применяться и для public-клиентов. 

Cферы использования

  1. Java приложения с гранулярной авторизаций
  2. Мультитенантные приложения
  3. Приложения с динамическими правами доступа
  4. Spring-based приложения

Easy-abac framework

Фреймворк был разработан на основе вышеописанных поставленных целей и способов.

Давайте рассмотрим данный фреймворк в использовании на простом Spring Boot проекте.Для начала добавим зависимость в проект (будем использовать maven):

На момент написания статьи последней версией является 1.1.

Добавляем конфигурацию, это нужно для подключения аспектов фреймворка:

Resource owner password credentials flow

По текущим рекомендациям безопасности описанных в

, данный flow не рекомендуется использовать вовсе из-за явных проблем с безопасностью.

Абстрактный oauth 2.0. flow c применением access token

Мы рассмотрели роли, рассмотрели виды токенов, а также как выглядят scope. Посмотрим на flow предоставления доступа к сервису.

Ниже представлена абстрактная схема (или flow) взаимодействия между участниками. Все шаги на данной схеме выполняются строго сверху вниз. Разберём детальнее.

Клиент получает одобрение от resource owner, на основе которого ему выдаётся доступ к ресурсу. Всё просто. А будет ли так же просто, если мы добавим в эту схему работу с refresh token?

Абстрактный oauth 2.0. flow c применением refresh token

Первый и второй шаги опущены из данной схемы — они ничем не отличаются от схемы абстрактного flow выше.

Схема подробнее:

Авторизация в веб: какой она может быть?

Хочется собрать все известные на сегодняшний день «простые» методы авторизации/регистрации на веб-ресурсах и их особенности в одном месте. (простые — в смысле не требующие специальных устройств, например смарт карт, устройств для сканирования отпечатков пальцев, сетчатки глаз и т.д.) Что ж, попробуем…

На данный момент мне известны такие способы:

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

2. Авторизация по OpenID
Довольно интересный метод авторизации, для осуществления которого необходима регистрация у т.н. «провайдера идентификации» и «зависимая сторона» — конечный ресурс (сайт), который пытается идентифицировать пользователя. Особенность данного метода заключается в том, что регистрация на самом сайте не требуется, а провайдер идентификации может быть один для многих сайтов.
Подробнее можно узнать например тут: http://ru.wikipedia.org/wiki/OpenID
Плюсы: один общий логин и пароль для одного провайдера, а значит и для всех ресурсов, удобство (не нужно запомниать множество учетных записей для разных сайтов), скорость использования, безопасность (пароль от учетной записи провайдера не передается конечному ресурсу (исключая случаи фишинга), а также исключен перехват)
Минусы: пока еще малая распространенность метода, сайты, необходимые большинству пользователей и поддерживающие OpenID можно пересчитать по пальцам, да и централизованность это тоже не всегда хорошо.
Примеры сайтов, использующих метод: ЖЖ, Мой круг
Пример провайдера идентификации: MyOpenID.com
Вариации метода: «цифровой паспорт .NET» — проприетарная разработка Майкрософт, однако получившая некоторое распространение.

Ну это из более-менее популярных. Теперь рассмотрим «экзотику»:

3. Enum — авторизация
Суть метода: привязка «аккаунта» мобильному телефону, номеру. При регистрации на сайте такого провайдера пользователю выдается ссылка, по которой он устанавливает java-приложение себе в телефон. Для авторизации, на сайтах поддерживающих этот метод пользователь вводит свой адрес электорнной почты, сайт в ответ показывает пользователю число, которое необходимо ввести в ранее установленное приложение. После ввода контрольного числа на экране мобильного телефона отображается число-результат, которое затем необходимо ввести обратно на сайт, на котором происходит авторизация.
Чем-то напоминает OpenID, поэтому и наследует некоторые его особенности:
Плюсы решения: простота реализации и пользования, безопасность (метод исключает перехват учетных данных, пригодных для повторной авторизации)
Минусы: малое распространение метода, привязка к телефону, который может быть украден или потерян, или просто может не находиться рядом в нужный момент. Пример enum-провайдера

4.
Я даже затрудняюсь как-либо назвать этот метод. Универсальный аккаунт чтоли. Впервые я увидел его на сайте Российского Jabber-сообщества Суть метода в том, что чтобы писать комментарии на этом сайте нужен зарегистрированный аккаунт, но не объязательно на самом jabber.ru, а вообще на любом jabber-сервере! Удобно на самом деле.
(на момент написания опуса метод не работает, происходит ошибка подключения к удаленному серверу и движок считает введенный пароль не верным, пробовал на аккаунте gmail.com, раньше вот работало…)
Ну с плюсами и минусами вроде очевидно: Jabber сейчас у многих, аккаунты есть — удобно. Но тут сразу возникает вопрос доверия сайту, ведь зайдя под своей учеткой один раз — недобропорядочный администратор может сделать это еще раз — это минус. Также все-таки сайт можно считать «тематическим» и подобный метод на другом сайте будет просто неоправдан, по причине различной аудитории.

5. Авторизация сертификатами
Не считаю нужным расписывать подробнее по той причине, что реализовано это может быть очень по-разному, от установки сертификата на компьютер (те же OpenID провайдеры, например MyOpenID.com) до более простого способа… Живую реализацию этого метода я видел и использовал только один раз — на форуме Античата — там можно после обычной регистрации зайти в профиль и скачать себе «сертификат» — файлик с ключем, затем запрятать его в укромное место и забыть. А вспомнить о нем только в случае потери пароля — сертификат поможет сбросить забытый пароль. Не авторизация в чистом виде, зато про сертификаты 🙂 Также можно почитать еще про сертификаты.

6. «Разовая» авторизация по ссылке
Сразу пример: после обычной регистрации на каком-нибудь форуме, на указанный электронный адрес высылаестя письмо со ссылкой — подтверждением адреса. Ссылка работает только один раз, цель у нее тоже одна — подтвердить что именно хозяин этого адреса зарегистрировался на том форуме, но при этом иногда при переходе по такой ссылке пользователь попадает сразу в свой аккаунт, не вводя логин и пароль, что тоже удобно. Подобный метод используется также для сброса пароля. В общем тоже метод авторизации.

Выводы:
Некоторые из этих методов чем-то похожи друг на друга, но обладают различным набором достоинств и недостатков. При этом 2 — 6 метод никак не обходятся без первоначальной «простой» регистрации и авторизации.
А это я все к чему? А к тому, что создавая очередной проект, вопрос авторизации/регистрации пользователей нужно хорошо продумывать.

ЗЫ Жду конструктивной критики.

UPD:
Всем спасибо за комментарии и исправления, также прошу прощения, что не смог принять активного участия в обсуждении — не было возможности из-за учебы. 🙂

Аутентификация по ключам доступа

Этот способ чаще всего используется для аутентификации устройств, сервисов или других приложений при обращении к веб-сервисам. Здесь в качестве секрета применяются ключи доступа (
access key, API key

Аутентификация по одноразовым паролям

Аутентификация по одноразовым паролям обычно применяется дополнительно к аутентификации по паролям для реализации
two-factor authentication
(2FA). В этой концепции пользователю необходимо предоставить данные двух типов для входа в систему: что-то, что он знает (например, пароль), и что-то, чем он владеет (например, устройство для генерации одноразовых паролей). Наличие двух факторов позволяет в значительной степени увеличить уровень безопасности, что м. б. востребовано для определенных видов веб-приложений.

Другой популярный сценарий использования одноразовых паролей — дополнительная аутентификация пользователя во время выполнения важных действий: перевод денег, изменение настроек и т. п.

Существуют разные источники для создания одноразовых паролей. Наиболее популярные:

  1. Аппаратные или программные токены, которые могут генерировать одноразовые пароли на основании секретного ключа, введенного в них, и текущего времени. Секретные ключи пользователей, являющиеся фактором владения, также хранятся на сервере, что позволяет выполнить проверку введенных одноразовых паролей. Пример аппаратной реализаций токенов — RSA SecurID; программной — приложение Google Authenticator.
  2. Случайно генерируемые коды, передаваемые пользователю через SMS или другой канал связи. В этой ситуации фактор владения — телефон пользователя (точнее — SIM-карта, привязанная к определенному номеру).
  3. Распечатка или scratch card со списком заранее сформированных одноразовых паролей. Для каждого нового входа в систему требуется ввести новый одноразовый пароль с указанным номером.

Что такое авторизация? | Энциклопедия «Касперского»
Аппаратный токен RSA SecurID генерирует новый код каждые 30 секунд.

В веб-приложениях такой механизм аутентификации часто реализуется посредством расширения forms authentication: после первичной аутентификации по паролю, создается сессия пользователя, однако в контексте этой сессии пользователь не имеет доступа к приложению до тех пор, пока он не выполнит дополнительную аутентификацию по одноразовому паролю.

Аутентификация по сертификатам

Сертификат представляет собой набор атрибутов, идентифицирующих владельца, подписанный
certificate authority
(CA). CA выступает в роли посредника, который гарантирует подлинность сертификатов (по аналогии с ФМС, выпускающей паспорта). Также сертификат криптографически связан с закрытым ключом, который хранится у владельца сертификата и позволяет однозначно подтвердить факт владения сертификатом.

На стороне клиента сертификат вместе с закрытым ключом могут храниться в операционной системе, в браузере, в файле, на отдельном физическом устройстве (smart card, USB token). Обычно закрытый ключ дополнительно защищен паролем или PIN-кодом.

В веб-приложениях традиционно используют сертификаты стандарта X.509. Аутентификация с помощью X.509-сертификата происходит в момент соединения с сервером и является частью протокола SSL/TLS. Этот механизм также хорошо поддерживается браузерами, которые позволяют пользователю выбрать и применить сертификат, если веб-сайт допускает такой способ аутентификации.

Что такое авторизация? | Энциклопедия «Касперского»
Использование сертификата для аутентификации.

Во время аутентификации сервер выполняет проверку сертификата на основании следующих правил:

  1. Сертификат должен быть подписан доверенным certification authority (проверка цепочки сертификатов).
  2. Сертификат должен быть действительным на текущую дату (проверка срока действия).
  3. Сертификат не должен быть отозван соответствующим CA (проверка списков исключения).

Что такое авторизация? | Энциклопедия «Касперского»
Пример X.509 сертификата.

После успешной аутентификации веб-приложение может выполнить авторизацию запроса на основании таких данных сертификата, как subject (имя владельца), issuer (эмитент), serial number (серийный номер сертификата) или thumbprint (отпечаток открытого ключа сертификата).

Использование сертификатов для аутентификации — куда более надежный способ, чем аутентификация посредством паролей. Это достигается созданием в процессе аутентификации цифровой подписи, наличие которой доказывает факт применения закрытого ключа в конкретной ситуации (non-repudiation).

Аутентификация по токенам

Такой способ аутентификации чаще всего применяется при построении распределенных систем
Single Sign-On
(SSO), где одно приложение (
service provider
или
relying party
) делегирует функцию аутентификации пользователей другому приложению (
identity provider
или
authentication service
). Типичный пример этого способа — вход в приложение через учетную запись в социальных сетях. Здесь социальные сети являются сервисами аутентификации, а приложение
доверяет
функцию аутентификации пользователей социальным сетям.

Реализация этого способа заключается в том, что identity provider (IP) предоставляет достоверные сведения о пользователе в виде токена, а service provider (SP) приложение использует этот токен для идентификации, аутентификации и авторизации пользователя.На общем уровне, весь процесс выглядит следующим образом:

  1. Клиент аутентифицируется в identity provider одним из способов, специфичным для него (пароль, ключ доступа, сертификат, Kerberos, итд.).
  2. Клиент просит identity provider предоставить ему токен для конкретного SP-приложения. Identity provider генерирует токен и отправляет его клиенту.
  3. Клиент аутентифицируется в SP-приложении при помощи этого токена.

Что такое авторизация? | Энциклопедия «Касперского»
Пример аутентификации «активного» клиента при помощи токена, переданного посредством Bearer схемы.

Процесс, описанный выше, отражает механизм аутентификации активного клиента, т. е. такого, который может выполнять запрограммированную последовательность действий (например, iOS/Android приложения). Браузер же — пассивный клиент в том смысле, что он только может отображать страницы, запрошенные пользователем.

Что такое авторизация? | Энциклопедия «Касперского»
Пример аутентификации «пассивного» клиента посредством перенаправления запросов.

Существует несколько стандартов, в точности определяющих протокол взаимодействия между клиентами (активными и пассивными) и IP/SP-приложениями и формат поддерживаемых токенов. Среди наиболее популярных стандартов — OAuth, OpenID Connect, SAML, и WS-Federation. Некоторая информация об этих протоколах — ниже в статье.

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

При аутентификации с помощью токена SP-приложение должно выполнить следующие проверки:

  1. Токен был выдан доверенным identity provider приложением (проверка поля issuer).
  2. Токен предназначается текущему SP-приложению (проверка поля audience).
  3. Срок действия токена еще не истек (проверка поля expiration date).
  4. Токен подлинный и не был изменен (проверка подписи).

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

Виды авторизации

Существует несколько моделей авторизации. Три основные — ролевая, избирательная и мандатная.

  • Ролевая модель. Администратор назначает пользователю одну или несколько ролей, а уже им выдает разрешения и привилегии. Эта модель применяется во многих прикладных программах и операционных системах.

    Например, все пользователи с ролью «Кассир» имеют доступ к кассовым операциям в бухгалтерской системе, а пользователи с ролью «Товаровед» — нет, зато у них есть доступ к складским операциям, при этом обе роли имеют доступ к общей ленте новостей.

  • Избирательная модель. Права доступа к конкретному объекту выдают конкретному пользователю. При этом право определять уровень доступа имеет либо владелец конкретного объекта (например, его создатель), либо суперпользователь (по сути, владелец всех объектов в системе). Кроме того, пользователь, обладающий определенным уровнем доступа, может передавать назначенные ему права другим.

    Например, пользователь А, создав текстовый файл, может назначить пользователю Б права на чтение этого файла, а пользователю В — права на его чтение и изменение. При этом пользователи Б и В могут передать свои права пользователю Г.

    Избирательная модель применяется в некоторых операционных системах, например в семействах Windows NT (в том числе в Windows 10) и Unix. По этой же модели предоставляется доступ, скажем, к документам на диске Google.

  • Мандатная модель. Администратор назначает каждому элементу системы определенный уровень конфиденциальности. Пользователи получают уровень доступа, определяющий, с какими объектами они могут работать. Обычно такая модель является иерархической, то есть высокий уровень доступа включает в себя права на работу и со всеми младшими уровнями.

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

    Например, в организации может быть пять уровней доступа. Пользователь, имеющий доступ к файлам 3-го уровня, может также открывать файлы 1-го и 2-го уровня, но не может работать с файлами 4-го и 5-го уровня.

Дальнейшее развитие фреймворка

На данный момент фреймворк включает базовый механизм авторизации, причем довольно гибкий. Рассматривается возможность встроенной реализации валидаторов “из коробки” по умолчанию.Также на данный момент фреймворк можеть быть использован только в spring-based приложениях. В будущем планируется избавиться от привязки к Spring.В планах и разработка более удобной и гибкой конфигурации.

Декларативный стиль

Реализацию авторизации декларативно можно выполнить различными способами: при помощи файлов конфигурации (например xml, yaml, properties), используя java annotations.Было решено остановиться на последнем, в силу того, что:

  1. Java annotations это инструмент как самого языка java, так и JVM, что позволяет обрабатывать аннотации как во время runtime, так и во время compile time.
  2. Аннотации удобны в использовании, т.к. сразу наглядно видно какой ресурс чем ограничен.
  3. Аннотации достаточно гибки в конфигурации, т.к. являются частью языка java.

Задача auth

Проблема авторизации в десятках сервисов встречалась ещё несколько лет назад — в начале «

». Эту проблему решили новым сервисом, который назвали – Auth. Он помог реализовать бесшовную аутентификацию в различных сервисах и перенести данные о пользователях в отдельные базы данных. 

У сервиса Auth есть три основные задачи:

Конфигурация и обработка ошибок

Данный пункт заслуживает особого внимания. Пару раз приходилось сталкиваться с хорошими фреймворками и библиотеками с плохой обработкой ошибок, особенно в части конфигурации. В таком случае отсутствие подробной документации делает фреймворк просто бесполезным.

Как уже говорилось, было решено использовать java annotations для реализации авторизации в декларативном стиле. Еще одним преимуществом такого выбора является обработка ошибок конфигурации во время компиляции — т.е. на более ранней стадии. Java предоставляет механизм Annotation Processing, который позволяет обрабатывать аннотации во время компиляции программы.

Тут еще можно в пример привести Java Module System, разработанную Oracle, которая вышла вместе с JDK 9, одним из важных достоинств которой является именно обработка ошибок во время компиляции.

Подходы к созданию фреймворка

Как обычно, прежде чем разрабатывать что-то новое нужно определиться с тем, какие проблемы будут решаться, чем фреймворк будет удобен и полезен и, возможно, уже есть готовое решение (об этом поговорим после).

Всем известны два стиля написания кода — императивный и декларативный. Императивный стиль описывает то, как получить результат, декларативный — что требуется получить в результате.

Декларативный стиль удобен тем, что нужно минимум усилий и времени, чтобы обозначить желаемый результат. Например, для авторизации это может быть сделано в виде описания ролей пользователя для доступа к ресурсу, разрешений (permissions) и т.д.Однако все задачи (как минимум для целей авторизации) декларативный стиль не решает, да и не может решить.

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

Права доступа

Права доступа выдаются клиенту в виде scope. Scope – это параметр, который состоит из разделённых пробелами строк — scope-token.

Каждый из scope-token представляет определённые права, выдающиеся клиенту. Например, scope-token doc_read может предоставлять доступ на чтение к какому-то документу на resource server, а employee — доступ к функционалу приложения только для работников фирмы. Итоговый scope может выглядеть так: email doc_read employee.

В OAuth 2.0 мы сами создаём scope-token, настраивая их под свои нужды. Имена scope-token ограничиваются только фантазией и двумя символами таблицы ASCII — ” и .

На этапе регистрации клиента, в настройках сервиса авторизации клиенту выдаётся стандартный scope по умолчанию. Но клиент может запросить у сервера авторизации scope, отличный от стандартного. В зависимости от политик на сервере авторизации и выбора владельца ресурса, итоговый набор scope может выглядеть совсем иначе.

Предыстория

За много лет работы в IT приходилось сталкиваться с проектами в самых разных сферах. У каждого проекта были свои требования к безопасности. Если в части аутентификации все было более-менее одинаково с точки зрения требований, то способы реализации механизма авторизации получались довольно разными от проекта к проекту.

Каждый раз авторизацию приходилось писать практически с нуля под конкретные цели проекта, разрабатывать архитектурное решение, потом дорабатывать с изменением требований, тестировать, и т.д. — все это обычный процесс, которого не избежать в разработке.

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

Проблемы

Первая версия Auth — часть монолита. Он использует свой собственный протокол общения с сервисами. Такая «схема» была необходима в тот момент, но за несколько лет работы проявились проблемы.

Auth — часть монолита. Следовательно, сервис привязан к релизному циклу, что лишает возможности независимой разработки и деплоя. Кроме того, придется разворачивать весь монолит, если захотелось развернуть Auth, например, при масштабировании сервиса.

Dodo IS зависит от Auth. В старой реализации внешние сервисы обращаются к Auth при каждом действии пользователя, чтобы валидировать данные о нём. Настолько сильная привязка может привести к остановке работы всей Dodo IS, если Auth «приляжет» по какой-то причине.

Auth зависит от Redis. Притом достаточно сильно — неисправность работы Redis’а приведёт к падению Auth’а. Мы используем Azure Redis, для которого заявленный SLA 99,9%. Это значит, что сервис может быть недоступен до 44 минут в месяц. Такие простои не позволительны.

Текущая реализация Auth использует свой протокол аутентификации, не опираясь на стандарты. В большинстве своих сервисов мы используем C# (если говорим о backend) и у нас нет проблем с поддержкой библиотеки для нашего протокола. Но если вдруг появятся сервисы на Python, Go или Rust, разработка и поддержка библиотек под эти языки потребует дополнительных затрат времени и принесет дополнительные сложности.

Текущий Auth использует схему Roles Based Access Control, которая базируется на ролях. Обычно с ролью выдаётся полный доступ к определённому сервису, вместо привязки к конкретному функционалу. Например, в пиццериях есть заместители управляющего, которые могут вести определенные проекты: составлять графики или учитывать сырьё.

Проблемы подтолкнули к тому, чтобы спроектировать и написать новую версию Auth. На старте проекта мы потратили 3 недели только на изучение стандартов авторизации и аутентификации OAuth 2.0 и OpenID Connect 1.0. 

Примечание. Утрированно, статья — это пересказ RFC, который приходилось перечитывать несколько раз, чтобы понять, что происходит вокруг. Здесь я постарался уйти от этой сложности и рассказать всё максимально просто, структурировано, кратко и без описания сложных вещей, например, какие символы может содержать в себе ответ сервиса.

Разница между авторизацией, аутентификацией и идентификацией

Авторизацию не следует путать с идентификацией и аутентификацией пользователя. Она происходит по завершении этих процессов.

Регистрация клиента

Способ регистрации клиента, например, ручной или service discovery, вы выбираете сами, в зависимости от

фантазии

конкретной реализации. Но при любом способе при регистрации, кроме ID клиента, должны быть обязательно указаны 2 параметра: redirection URI и client type.

Redirection URI — адрес, на который отправится владелец ресурса после успешной авторизации. Кроме авторизации, адрес используется для подтверждения, что сервис, который обратился за авторизацией, тот, за кого себя выдаёт.

Client type — тип клиента, от которого зависит способ взаимодействия с ним. Тип клиента определяется его возможностью безопасно хранить свои учётные данные для авторизации — токен. Поэтому существует всего 2 типа клиентов:

Создание фреймворка для авторизации

При создании фреймворка было решено преследовать следующие цели:

  1. Простота в использовании — чтобы избавить пользователей от чтения многостраничного мануала, настроек и т.д.
  2. Гибкость — фреймворк должен адаптироваться под различные цели и приложения
  3. Надежная обработка ошибок

Способ реализации авторизации

Есть много способов реализации:

Сравнительный анализ

Разумеется, перед тем как писать что-то новое, нужно убедиться в том, что такое решение еще не было создано кем-то другим. Также рассмотреть похожие решения и определить насколько они подходят или не подходят для решения поставленной задачи, собственно, что и было проделано:

Рассмотрены следующие инструменты для авторизации: Apache Shiro, JAAS, Spring Security.Apache Shiro и JAAS не предоставляют достаточной гибкости, имеют не очень удобный интерфейс конфигурации, JAAS вообще не использует декларативный стиль, Apache Shiro — только через файл конфигурации — несомненно, данные фреймворки удобны для решения некоторых задач, ноЧто же касается Spring Security — это довольно мощный механизм и к тому же очень гибкий (как и положено быть фреймворку такого уровня), использует декларативный стиль для авторизации, однако не имеет встроенного механизма проверки конфигурации во время compile-time.

В заключение можно сказать что Easy-ABAC Framework с одной стороны решает проблемы которые есть у других фреймворков, дополняет их, с другой — …

Стандарт saml

Стандарт Security Assertion Markup Language (SAML) описывает способы взаимодействия и протоколы между identity provider и service provider для обмена данными аутентификации и авторизации посредством токенов. Изначально версии 1.0 и 1.1 были выпущены в 2002 – 2003 гг., в то время как версия 2.0, значительно расширяющая стандарт и обратно несовместимая, опубликована в 2005 г.

Этот основополагающий стандарт — достаточно сложный и поддерживает много различных сценариев интеграции систем. Основные «строительные блоки» стандарта:

Стандарты ws-trust и ws-federation

WS-Trust и WS-Federation входят в группу стандартов WS-*, описывающих SOAP/XML-веб сервисы. Эти стандарты разрабатываются группой компаний, куда входят Microsoft, IBM, VeriSign и другие. Наряду с SAML, эти стандарты достаточно сложные, используются преимущественно в корпоративных сценариях.

Стандарт WS-Trust описывает интерфейс сервиса авторизации, именуемого Secure Token Service (STS). Этот сервис работает по протоколу SOAP и поддерживает создание, обновление и аннулирование токенов. При этом стандарт допускает использование токенов различного формата, однако на практике в основном используются SAML-токены.

Стандарт WS-Federation касается механизмов взаимодействия сервисов между компаниями, в частности, протоколов обмена токенов. При этом WS-Federation расширяет функции и интерфейс сервиса STS, описанного в стандарте WS-Trust. Среди прочего, стандарт WS-Federation определяет:

Можно сказать, что WS-Federation позволяет решить те же задачи, что и SAML, однако их подходы и реализация в некоторой степени отличаются.

Токены

Токен в OAuth 2.0 — это строка, непрозрачная для клиента. Обычно строка выглядит как случайно сгенерированная — её формат не имеет значения для клиента. Токен — это ключ доступа к чему-либо, например, к защищённому ресурсу (access token) или к новому токену (refresh Token).

У каждого токена своё время жизни. Но у refresh token оно должно быть больше, т.к. он используется для получения access token. Например, если срок жизни access token около часа, то refresh token можно оставить жить на целую неделю. 

Refresh token опционален и доступен только для confedential клиентов. Пользуясь опциональностью токена, в некоторых реализациях время жизни access token сделано очень большим, а refresh token вообще не используется, чтобы не заморачиваться с обновлением.

За access token закреплён определённый набор прав доступа, который выдаётся клиенту во время авторизации. Давайте разберёмся, как выглядят права доступа в OAuth 2.0.

Уровень абстракции

Абстракция во фреймворке выполнена следующим образом:

Форматы токенов

Существует несколько распространенных форматов токенов для веб-приложений:

Вместо вывода


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

Если хотите погрузиться в тематику детальнее, то рекомендую в RFC 6749 (для OAuth 2.0) и RFC 8628 (для Device Flow). Кроме того, следить за актуальными версиями RFC можно на ресурсе, посвящённому OAuth.

Если статья была полезна и захотите подробностей — пишите в комментариях, и в следующих статьях расскажу о PKCE, о протоколе аутентификации OpenID Connect 1.0, о нашей реализации сервера аутентификации и многом другом.

Полезные ссылки:

Заключение

В статье рассмотрены архитектурные подходы к авторизации, предствлен Easy-ABAC Framework.Среди преимуществ разработанного фреймворка можно отметить:

  1. Декларативный стиль авторизации
  2. Обработка ошибок конфигурации во время компиляции
  3. Простая и понятная конфигурация
  4. Гибкость
Похожее:  Пользовательское соглашение об использовании сайта - Ситилинк

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *