Этим постом я хочу открыть ветку статей посвященную IdentityServer4. Начнем мы с основных понятий.
Самым перспективным на текущий момент протоколом аутентификации является OpenID Connect, а протоколом авторизации (предоставления доступа) является OAuth 2.0. IdentityServer4 реализует эти два протокола. Он оптимизирован для решения типичных проблем безопасности.
OpenID Connect — это протокол и стандарт аутентификации, он не дает доступ к ресурсам (Web API), но т.к. он разработан поверх протокола авторизации OAuth 2.0, он позволяет получить параметры профиля пользователя как будто вы получили доступ к ресурсу UserInfo.
JWT (JSON Web Token) представляет собой веб-стандарт, который определяет способ передачи данных о пользователе в формате JSON в зашифрованном виде.
OAuth 2.0 (RFC 6749) — это протокол и стандарт авторизации. Он позволяет приложениям получить доступ к защищенным ресурсам, например к Web API.
Взглянем на диаграмму обращения к защищенному ресурсу и разберемся с основными шагами и принятой терминологией:
-
Клиент запрашивает у пользователя разрешение пройти авторизацию от его имени. Клиент — это клиентское приложение обращающиеся к защищённым ресурсам от имени владельца ресурсов. Ресурс — это все наши защищенные сервисы Web API.
-
User разрешает клиентскому приложению пройти авторизацию от его имени, например, вводит логин и пароль. Логин и пароль будут являться грантом авторизации для клиентского приложения. User (владелец ресурса) — программа или человек, который может выдать доступ к защищённым ресурсам, например, путем ввода логина (username) и пароля (password);
-
Клиентское приложение запрашивает токен доступа у
IdentityServer4
путём предоставления информации о самом себе (client_id
,client_secret
), предоставления разрешения на авторизацию от пользователя (username
,password
) и предоставленияgrant_type
иscope
. Затем сервер авторизации проверяет подлинность клиента и реквизиты владельца ресурса (логин и пароль).Протокол OAuth 2.0 проводит аутентификации не только пользователя, но и клиентского приложения, осуществляющего доступ к ресурсам. Для этого протокол предусматривает такие параметры как client_id и client_secret.
сlient_id — это идентификатор клиентского приложения, используемыйIdentityServer4
для поиска информации о клиенте.
client_secret является аналогом пароля для клиентского приложения и используется для аутентификации клиентского приложения наIdentityServer4
. Секрет клиента должен быть известен только приложению и API. Исходя из вышесказанного делаем вывод что IdentityServer4 должен знать о своих клиентах. -
Если подлинность приложения подтверждена и разрешение на авторизацию действительно,
IdentiryServer4
создаётaccess-токен
(токен доступа) для приложения и необязательный ключ обновления (refresh-токен
). Процесс авторизации завершён. Если запрос недопустимый или несанкционированный, то сервер авторизации возвращает код с соответствующим сообщением об ошибке. -
Клентское приложение обращается за данными к защищенному Web API, предоставляя при этом токен доступа для авторизации. Если код ответа сервера ресурсов 401, 403 или 498, то токен доступа, используемый для аутентификации, недействителен или просрочен.
-
Если токен действителен,
Web API
предоставляет данные приложению.
Типы токенов
Зарегистрированным в IdentityServer4
клиентам позволено запрашивать у IdentityServer4
identity
-токен, access
-токен и refresh
-токен.
- identity-токен (токен идентификации) — результат процесса аутентификации. Содержит идентификатор пользователя и информации о том, как и когда пользователь проходит аутентификацию. Можно расширить своими данными.
- access-токен (токен доступа) — передается защищенному API и используется им для авторизации (разрешения доступа) к своим данным.
- refresh-токен (токен обновления) — необязательный параметр, который сервер авторизации может возвратить в ответ на запрос токена доступа.
Введем еще два понятия:
Authenticatation Server Url — конечная точка для получения ключа доступа. Все запросы на предоставление и возобновление ключей доступа будем направлять на этот URL-адрес.
Resource Url — URL-адрес защищенного ресурса, по которому нужно обращаться, чтобы получить доступ к нему, передавая ему ключ доступа в заголовке авторизации.
Запрос ключа доступа
Для запроса ключа доступа клиент делает POST
запрос к конечной точке IdentityServer4
со следующим заголовком
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': 'application/json',
'Expect': '100-continue'
и передавая следующие параметры:
'grant_type' : 'password',
'username' : login,
'password' : password,
'scope' : 'scope',
'client_id' : 'client_id',
'client_secret' : '{client_secret}'
username
, password
, client_id
и client_secret
были разобраны выше. Разберём остальные параметры:
grant_type — тип гранта или тип разрешения на авторизацию. Тип разрешения на авторизацию зависит от используемого приложением метода запроса авторизации, а также от того, какие типы разрешения поддерживаются со стороны API. В нашем случае он будет иметь значение password
, что согласно спецификации OAuth 2.0
соответствует гранту реквизитов доступа владельца ресурса (авторизация по логину и паролю).
Протокол OAuth 2.0
определяет следующие типы грантов требующие обязательного взаимодействие с пользователям:
- код авторизации (authorization code). Является одним из наиболее распространённых типов разрешения на авторизацию, т.к. хорошо подходит для серверных приложений (server-side applications), где исходный код приложения и секрет клиента не доступны посторонним;
- неявный (implicit). Неявный тип разрешения на авторизацию используется мобильными и веб-приложениями, где конфиденциальность секрета клиента не может быть гарантирована;
И типы грантов, которые могут выполняться без интерактивного взаимодействия с пользователям:
- реквизиты владельца ресурса (resource owner). Этот тип разрешения стоит использовать только в том случае, когда клиентское приложение пользуется доверием пользователя и пользователь спокойно относится к вводу своего логина и пароля. Этот тип разрешения должен использоваться только в том случае, когда другие варианты не доступны. Данный тип разрешения удобен для корпоративных клиентов, которые в рамках своей системы уже использовали учетные данные пользователя и хотят перейти на
OAuth 2.0
. - учетные данные клиента. Используются при доступе приложения к API. Это может быть полезно, например, когда приложение хочет обновить собственную регистрационную информацию на сервисе или URI перенаправления, или же осуществлять доступ к другой информации, хранимой в аккаунте приложения на сервисе, через API сервиса.
scope — это необязательный параметр. Он определяет область видимости. Токен доступа, возвращенный сервером, будет обеспечивать доступ только к тем службам, которые входят в эту область. Т.е. мы можем несколько служб объединить под одним scope и если клиент получает ключ доступа к этому scope он получает доступ ко всем этим службам. Также scope может использоваться для ограничения прав авторизации (например, доступ на чтение или запись)
Автор: artemmatveev