Модуль для Апостол CRM.
-
Сервер авторизации разработан по стандартам:
-
Позволяет упростить доступ пользователей к приложениям, разрешив для этого использование существующей учетной записи социальной сети или, например, учетной записи пользователя в Google или в ЕСИА (Госуслуги).
Следуйте указаниям по сборке и установке Апостол CRM
Протокол определяет четыре роли:
- Владелец ресурса (
resource owner
) – Пользователь системы (физическое лицо); - Клиент (
client
) – Приложение, которое запрашивает доступ к защищаемому ресурсу от имени его владельца; - Сервер авторизации (
authorization server
) – сервер, который выпускает для клиента маркеры идентификации с разрешениями от владельца ресурса, а также маркеры доступа, позволяющие получать доступ к данным; - Поставщик ресурса (
resource server
) – сервер, обеспечивающий доступ к защищаемому ресурсу на основе проверки маркеров идентификации и маркеров доступа (например, к идентификационным данным пользователя).
В рамках данной системы authorization server
и resource server
- это один и тот же сервер.
Для взаимодействия Клиента
с Сервером
необходимо получить идентификатор (client_id
) и секрет (client_secret
).
Взаимодействие происходит через RESTful
API описанное в спецификации RFC 6749.
В общем виде схема аутентификация с использованием OpenID Connect выглядит следующим образом:
- Клиент (
client
) готовит запрос на аутентификацию пользователя с необходимыми параметрами; - Клиент (
client
) отправляетGET
запрос на аутентификацию в адрес сервера авторизации; - Сервер авторизации (
authorization server
) аутентифицирует пользователя (пользователь вводит логин и пароль); - Сервер авторизации (
authorization server
) получает согласие пользователя на проведение аутентификации в данной системе; - Сервер авторизации (
authorization server
) перенаправляет пользователя обратно Клиенту и передает код авторизации; - Клиент (
client
) отправляетPOST
запрос с использованием кода авторизации на получения маркера идентификации; - Клиент (
client
) получает ответ, содержащий необходимый маркер идентификации (меняет код авторизации на маркер доступа); - Клиент (
client
) проводит проверку маркера идентификации и извлекает из маркера идентификатор пользователя.
Далее детально будут рассмотрены формируемые Клиентом запросы и ответы от Сервера авторизации.
Для авторизации:
GET /oauth2/authorize
Для получения маркера доступа:
POST /oauth2/token
Протокол OAuth 2 определяет четыре разных типа разрешения на авторизацию, каждый из которых полезен в определённых ситуациях:
- Код авторизации (
Authorization Code
): используется с серверными приложениями (server-side applications). - Неявный (
Implicit
): используется мобильными или веб-приложениями (JavaScript), приложениями работающими на устройстве пользователя. - Учётные данные владельца ресурса (
Resource Owner Password Credentials
): используются доверенными приложениями, например приложениями, которые являются частью самого сервера. - Учётные данные клиента (
Client Credentials
): используются при доступе клиента (приложения) к API без авторизации пользователя.
- Код авторизации является одним из наиболее распространённых типов разрешения на авторизацию, поскольку он хорошо подходит для серверных приложений, где исходный код приложения и секрет клиента не доступны посторонним. Процесс в данном случае строится на перенаправлении (redirection), что означает, что приложение должно быть в состоянии взаимодействовать с пользовательским агентом (user-agent), например, веб-браузером, и получать коды авторизации API, перенаправляемые через пользовательский агент.
Параметры запроса:
Поле | Значение | Описание |
---|---|---|
client_id | client_id |
Обязательный. Идентификатор клиента (приложения). |
redirect_uri | redirect_uri |
Обязательный. URI, на который сервер авторизации перенаправит агента пользователя (браузер) и код авторизации. |
response_type | code | Обязательный. Указывает на то, что приложение запрашивает доступ с помощью кода авторизации. |
scope | scope |
Рекомендуемый. Список областей, разделенных пробелами, которые определяют ресурсы, к которым ваше приложение может получить доступ от имени пользователя. |
access_type | access_type |
Рекомендуемый. Указывает, может ли ваше приложение обновлять маркеры доступа, когда пользователь отсутствует в браузере. Допустимые значения параметров: online (по умолчанию) и offline. |
state | state |
Рекомендуемый. Набор случайных символов которые будут возвращены сервером клиенту (используется для защиты от повторных запросов). |
Пример зпроса:
GET /oauth2/authorize?client_id=YOUR-CLIENT-ID&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Foauth2%2Fcode&scope=api&response_type=code&access_type=online&state=c2FmZXR HTTP/1.1
Host: localhost:8080
http://localhost:8080/oauth2/authorize?
client_id=YOUR-CLIENT-ID&
redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Foauth2%2Fcode&
response_type=code&
access_type=online&
scope=api&
state=c2FmZXR
Если в ходе аутентификации не возникло ошибок, то сервер авторизации перенаправит пользователя по ссылке, указанной в redirect_uri
, а также вернёт два обязательных параметра:
- code – Код авторизации;
- state – Значение параметра
state
, которое было получено в запросе на аутентификацию;
Клиент должен провести сравнение отправленного и полученного параметра state
.
Ответ с кодом авторизации:
http://localhost:8080/oauth2/code?code=b%2F8NpjbB4eLaukGr68tE7maTCeBISO%2FC7hWxKGuKb8I4Ysc7uw8a2MRUMWnO3Nzt
- Обратите внимание, на то что код (
b/8NpjbB4eLaukGr68tE7maTCeBISO/C7hWxKGuKb8I4Ysc7uw8a2MRUMWnO3Nzt
) закодирован алгоритмом URL encode и его нужно будет декодировать алгоритмом URL Decode.
Если в ходе аутентификации возникла ошибка, то сервер авторизации перенаправит пользователя по ссылке, указанной в redirect_uri
с информацией об ошибке:
http://localhost:8080/oauth2/code?code=403&error=access_denied&error_description=Access%20denied.
Для обмена кода авторизации на маркер доступа Клиент должен сформировать запрос методом POST
.
Параметры запроса:
Поле | Значение | Описание |
---|---|---|
client_id | client_id |
Обязательный. Идентификатор клиента. |
client_secret | client_secret |
Обязательный. Секрет клиента. |
grant_type | authorization_code | Обязательный. Как определено в спецификации OAuth 2.0, это поле должно содержать значение authorization_code. |
code | code |
Обязательный. Код авторизации, возвращенный из первоначального запроса. |
redirect_uri | redirect_uri |
Обязательный. URI переадресации (должен совпадать с redirect_uri из первоначального запроса). |
- Согласно спецификации OAuth 2.0, параметры авторизации клиента (
client_id
иclient_secret
) могут быть переданы как в теле запроса так и в HTTP заголовкеAuthorization
(HTTP Basic authentication).
Authorization: Basic d2ViLXNlcnZpY2UucnU6Y2xpZW50IHNlY3JldA==
В ответ на запрос сервер авторизации, вернет объект JSON, который содержит маркер краткосрочного доступа и маркер обновления.
Ответ содержит следующие поля:
Поле | Тип | Описание |
---|---|---|
access_token | STRING | Маркер краткосрочного доступа (сроком действия 1 час). |
expires_in | INTEGER | Оставшееся время жизни маркера доступа в секундах. |
token_type | STRING | Тип возвращаемого маркера. Значение всегда будет Bearer. |
session | STRING | Идентификатор сессии пользователя. |
refresh_token | STRING | * Маркер который вы можете использовать для получения нового маркер доступа. |
id_token | STRING | * Маркер пользователя. |
- Обратите внимание, что маркер обновления возвращается только в том случае, если ваше приложение в первоначальном запросе к серверу авторизации, установило в
access_type
значение: offline. - Обратите внимание, что маркер пользователя возвращается только в том случае, если ваше приложение в первоначальном запросе к серверу авторизации, установило в
scope
одно из значений: openid, profile или email.
Пример зпроса:
POST http://localhost:8080/oauth2/token
Content-Type: application/x-www-form-urlencoded
client_id=YOUR-CLIENT-ID&
client_secret=YOUR-CLIENT-SECRET&
grant_type=authorization_code&
code=b%2F8NpjbB4eLaukGr68tE7maTCeBISO%2FC7hWxKGuKb8I4Ysc7uw8a2MRUMWnO3Nzt&
redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Foauth2%2Fcode
* Хоть это и не определено спецификацией, но сервер авторизации примет запрос и в формате JSON (Content-Type: application/json
)
Пример ответа:
{
"access_token" : "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiIDogImFjY291bnRzLnNoaXAtc2FmZXR5LnJ1IiwgImF1ZCIgOiAid2ViLXNoaXAtc2FmZXR5LnJ1IiwgInN1YiIgOiAiZGZlMDViNzhhNzZiNmFkOGUwZmNiZWYyNzA2NzE3OTNiODZhYTg0OCIsICJpYXQiIDogMTU5MzUzMjExMCwgImV4cCIgOiAxNTkzNTM1NzEwfQ.NorYsi-Ht826HUFCEArVZ60_dEUmYiJYXubnTyweIMg",
"token_type" : "Bearer",
"expires_in" : 3600,
"session" : "dfe05b78a76b6ad8e0fcbef270671793b86aa848"
}
-
Неявный тип разрешения на авторизацию используется мобильными и веб-приложениями (приложениями, которые работают в веб-браузере - JavaScript), где конфиденциальность секрета клиента не может быть гарантирована. Неявный тип разрешения также основан на перенаправлении пользовательского агента, при этом маркер доступа передаётся пользовательскому агенту для дальнейшей передачи приложению. Это, в свою очередь, делает маркер доступным пользователю и другим приложениям на устройстве пользователя. Также при этом типе разрешения на авторизацию не осуществляется аутентификация подлинности приложения, а сам процесс полагается на URI перенаправления (зарегистрированном ранее в сервере авторизации).
-
Неявный тип разрешения на авторизацию не поддерживает маркеры обновления (
refresh_token
) и маркера пользователя (id_token
).
Параметры запроса:
Поле | Значение | Описание |
---|---|---|
client_id | client_id |
Обязательный. Идентификатор клиента (приложения). |
redirect_uri | redirect_uri |
Обязательный. URI, на который сервер авторизации перенаправит агента пользователя (браузер) и маркер доступа. |
response_type | token | Обязательный. Приложения JavaScript должны установить значение параметра в token. Это значение указывает серверу авторизации возвращать маркер доступа в виде пары name = value в идентификаторе фрагмента URI (#), на который перенаправляется пользователь после завершения процесса авторизации. |
scope | scope |
Рекомендуемый. Список областей, разделенных пробелами, которые определяют ресурсы, к которым ваше приложение может получить доступ от имени пользователя. |
state | state |
Рекомендуемый. Набор случайных символов которые будут возвращены сервером клиенту (используется для защиты от повторных запросов). |
Пример зпроса:
GET /oauth2/authorize?client_id=YOUR-CLIENT-ID&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Foauth2%2Fcallback&scope=api&response_type=token&state=c2FmZXR HTTP/1.1
Host: localhost:8080
http://localhost:8080/oauth2/authorize?
client_id=YOUR-CLIENT-ID&
redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Foauth2%2Fcallback&
response_type=token&
scope=api&
state=c2FmZXR
Маркер доступа или сообщение об ошибке возвращаются во фрагменте хэша URI перенаправления, как показано ниже:
Ответ с маркером доступа:
http://localhost:8080/callback#token_type=Bearer&expires_in=3600&session=dfe05b78a76b6ad8e0fcbef270671793b86aa848&access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiIDogImFjY291bnRzLnNoaXAtc2FmZXR5LnJ1IiwgImF1ZCIgOiAid2ViLXNoaXAtc2FmZXR5LnJ1IiwgInN1YiIgOiAiZGZlMDViNzhhNzZiNmFkOGUwZmNiZWYyNzA2NzE3OTNiODZhYTg0OCIsICJpYXQiIDogMTU5MzUzMjExMCwgImV4cCIgOiAxNTkzNTM1NzEwfQ.NorYsi-Ht826HUFCEArVZ60_dEUmYiJYXubnTyweIMg
-
В дополнение к параметру
access_token
строка фрагмента также содержит параметрtoken_type
, который всегда имеет значение Bearer, и параметрexpires_in
, который указывает время жизни маркера в секундах. Если параметрstate
был указан в запросе маркера доступа, его значение также включается в ответ. -
URI перенаправления, в данном случае это
http://localhost:8080/callback/index.html
должен указывать на веб-страницу, которая содержит скрипт для извлечения маркера доступа из URI перенаправления.
Ответ с ошибкой:
http://localhost:8080/callback#code=403&error=access_denied&error_description=Access%20denied.
Сервер авторизации поддерживает гибридный режим типов разрешения. Если в параметре response_type
указать, через пробел, оба значения code token
, то сервер авторизации вернет в одном запросе и код авторизации и маркер доступа.
- При этом типе разрешения на авторизацию пользователь предоставляет приложению напрямую свои учётные данные (имя пользователя и пароль). Приложение, в свою очередь, использует полученные учётные данные пользователя для получения маркера доступа от сервера авторизации. Этот тип разрешения на авторизацию должен использоваться только в том случае, когда другие варианты не доступны. Кроме того, этот тип разрешения стоит использовать только в случае, когда приложение пользуется доверием пользователя (например, является частью самой системы).
После того, как пользователь передаст свои учётные данные приложению, приложение запросит маркер доступа у авторизационного сервера методом POST
.
Параметры запроса:
Поле | Значение | Описание |
---|---|---|
client_id | client_id |
Обязательный. Идентификатор клиента. |
client_secret | client_secret |
Обязательный. Секрет клиента. |
grant_type | password | Обязательный. Как определено в спецификации OAuth 2.0, это поле должно содержать значение password. |
username | username |
Вариативный. Логин пользователя. Игнорируется если указано значение в поле secret. |
password | password |
Вариативный. Пароль пользователя. Игнорируется если указано значение в поле secret. |
secret | secret |
Вариативный. Секретный код. Если значение указано то поля username и password заполнять не нужно. |
scope | scope |
Рекомендуемый. Список областей, разделенных пробелами, которые определяют ресурсы, к которым ваше приложение может получить доступ от имени пользователя. |
- Согласно спецификации OAuth 2.0, параметры авторизации клиента (
client_id
иclient_secret
) могут быть переданы как в теле запроса так и в HTTP заголовкеAuthorization
(HTTP Basic authentication).
Authorization: Basic d2ViLXNlcnZpY2UucnU6Y2xpZW50IHNlY3JldA==
В ответ на запрос сервер авторизации, вернет объект JSON, который содержит маркер краткосрочного доступа и маркер обновления.
Ответ содержит следующие поля:
Поле | Тип | Описание |
---|---|---|
access_token | STRING | Маркер краткосрочного доступа (сроком действия 1 час). |
expires_in | INTEGER | Оставшееся время жизни маркера доступа в секундах. |
token_type | STRING | Тип возвращаемого маркера. Значение всегда будет Bearer. |
session | STRING | Идентификатор сессии пользователя. |
refresh_token | STRING | Маркер который вы можете использовать для получения нового маркер доступа. |
id_token | STRING | * Маркер пользователя. |
- Обратите внимание, что маркер пользователя возвращается только в том случае, если ваше приложение в запросе к серверу авторизации, установило в
scope
одно из значений: openid, profile или email.
Пример зпроса:
POST http://localhost:8080/oauth2/token
Content-Type: application/x-www-form-urlencoded
client_id=YOUR-CLIENT-ID&
client_secret=YOUR-CLIENT-SECRET&
grant_type=password&
username=admin&
password=admin
* Хоть это и не определено спецификацией, но сервер авторизации примет запрос и в формате JSON (Content-Type: application/json
)
Если учётные данные и клиента и пользователя корректны, сервер авторизации вернёт маркер доступа для приложения.
- Тип разрешения на авторизацию с использованием учётных данных клиента позволяет приложению осуществлять доступ к своему собственному аккаунту сервиса. Это может быть полезно, например, когда приложение хочет обновить собственную регистрационную информацию на сервисе или URI перенаправления, или же осуществить доступ к другой информации, хранимой в аккаунте приложения на сервисе, через API.
Параметры запроса:
Поле | Значение | Описание |
---|---|---|
client_id | client_id |
Обязательный. Идентификатор клиента. |
client_secret | client_secret |
Обязательный. Секрет клиента. |
grant_type | client_credentials | Обязательный. Как определено в спецификации OAuth 2.0, это поле должно содержать значение client_credentials. |
scope | scope |
Рекомендуемый. Список областей, разделенных пробелами, которые определяют ресурсы, к которым ваше приложение может получить доступ от имени пользователя. |
- Согласно спецификации OAuth 2.0, параметры авторизации клиента (
client_id
иclient_secret
) могут быть переданы как в теле запроса так и в HTTP заголовкеAuthorization
(HTTP Basic authentication).
Authorization: Basic d2ViLXNlcnZpY2UucnU6Y2xpZW50IHNlY3JldA==
В ответ на запрос сервер авторизации, вернет объект JSON, который содержит маркер краткосрочного доступа и маркер обновления.
Ответ содержит следующие поля:
Поле | Тип | Описание |
---|---|---|
access_token | STRING | Маркер доступа (сроком действия 1 день). |
expires_in | INTEGER | Оставшееся время жизни маркера доступа в секундах. |
token_type | STRING | Тип возвращаемого маркера. Значение всегда будет Bearer. |
session | STRING | Идентификатор сессии пользователя. |
refresh_token | STRING | Маркер который вы можете использовать для получения нового маркер доступа. |
id_token | STRING | * Маркер пользователя. |
- Обратите внимание, что маркер пользователя возвращается только в том случае, если ваше приложение в запросе к серверу авторизации, установило в
scope
одно из значений: openid, profile или email.
Пример зпроса:
POST http://localhost:8080/oauth2/token
Content-Type: application/x-www-form-urlencoded
client_id=YOUR-CLIENT-ID&
client_secret=YOUR-CLIENT-SECRET&
grant_type=client_credentials
- После истечения срока действия маркера доступа все запросы к API с его использованием будут возвращать ошибку с кодом
403
("Token expired"). Если при создании маркера доступа был создан и маркер для обновления маркера доступа (refresh_token
), последний может быть использован для получения нового маркера доступа от сервера авторизации.
Параметры запроса:
Поле | Значение | Описание |
---|---|---|
client_id | client_id |
Обязательный. Идентификатор клиента. |
client_secret | client_secret |
Обязательный. Секрет клиента. |
grant_type | refresh_token | Обязательный. Как определено в спецификации OAuth 2.0, это поле должно содержать значение refresh_token. |
refresh_token | refresh_token |
Обязательный. Маркер обновления, выданный ранее. |
scope | scope |
Рекомендуемый. Список областей, разделенных пробелами, которые определяют ресурсы, к которым ваше приложение может получить доступ от имени пользователя. |
- Согласно спецификации OAuth 2.0, параметры авторизации клиента (
client_id
иclient_secret
) могут быть переданы как в теле запроса так и в HTTP заголовкеAuthorization
(HTTP Basic authentication).
Authorization: Basic d2ViLXNlcnZpY2UucnU6Y2xpZW50IHNlY3JldA==
Пример зпроса:
POST http://localhost:8080/oauth2/token
Content-Type: application/x-www-form-urlencoded
client_id=YOUR-CLIENT-ID&
client_secret=YOUR-CLIENT-SECRET&
grant_type=refresh_token&
refresh_token=e%2FdtGmXCIzHvPMURn%2FTH9udTPxtKpR5FFifx2uvH1WqT4myXLtgyjkLgYDy7g3Ik5MrFRR82
* Хоть это и не определено спецификацией, но сервер авторизации примет запрос и в формате JSON (Content-Type: application/json
)
Если учётные данные клиента корректны, то сервер авторизации вернёт новый маркер краткосрочного доступа и новый маркер обновления.
- Грант на продление позволяет получить новый маркер доступа до истечения срока его действия.
Параметры запроса:
Поле | Значение | Описание |
---|---|---|
client_id | client_id |
Обязательный. Идентификатор клиента. |
client_secret | client_secret |
Обязательный. Секрет клиента. |
grant_type | urn:ietf:params:oauth:grant-type:token-exchange | Обязательный. Как определено в спецификации, это поле должно содержать значение urn:ietf:params:oauth:grant-type:token-exchange. |
subject_token | subject_token |
Обязательный. Маркер, выданный ранее. |
subject_token_type | subject_token_type |
Рекомендуемый. Тип передаваемого маркера. Доступные значения: urn:ietf:params:oauth:token-type:jwt (по умолчанию), urn:ietf:params:oauth:token-type:access_token, urn:ietf:params:oauth:token-type:refresh_token, urn:ietf:params:oauth:token-type:id_token. |
scope | scope |
Рекомендуемый. Список областей, разделенных пробелами, которые определяют ресурсы, к которым ваше приложение может получить доступ от имени пользователя. |
- Согласно спецификации OAuth 2.0, параметры авторизации клиента (
client_id
иclient_secret
) могут быть переданы как в теле запроса так и в HTTP заголовкеAuthorization
(HTTP Basic authentication).
Authorization: Basic d2ViLXNlcnZpY2UucnU6Y2xpZW50IHNlY3JldA==
Пример зпроса:
POST http://localhost:8080/oauth2/token
Content-Type: application/x-www-form-urlencoded
client_id=YOUR-CLIENT-ID&
client_secret=YOUR-CLIENT-SECRET&
grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Atoken-exchange&
subject_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.[сокращенно для краткости].NorYsi-Ht826HUFCEArVZ60_dEUmYiJYXubnTyweIMg&
subject_token_type=urn%3Aietf%3Aparams%3Aoauth%3Atoken-type%3Ajwt
* Хоть это и не определено спецификацией, но сервер авторизации примет запрос и в формате JSON (Content-Type: application/json
)
Если учётные данные клиента корректны и у переданного маркера доступа не истек срок, то сервер авторизации вернёт новый маркер краткосрочного доступа и новый маркер обновления.
- Данный тип гранта позволяет авторизоваться в системе по данным из JWT маркера выпущенного другой (внешней) системой, например Google.
Параметры запроса:
Поле | Значение | Описание |
---|---|---|
client_id | client_id |
Обязательный. Идентификатор клиента. |
client_secret | client_secret |
Обязательный. Секрет клиента. |
grant_type | urn:ietf:params:oauth:grant-type:jwt-bearer | Обязательный. Это поле должно содержать значение urn:ietf:params:oauth:grant-type:jwt-bearer. |
assertion | assertion |
Обязательный. Маркер JWT выданный другой (внешней) системой. |
- Согласно спецификации OAuth 2.0, параметры авторизации клиента (
client_id
иclient_secret
) могут быть переданы как в теле запроса так и в HTTP заголовкеAuthorization
(HTTP Basic authentication).
Authorization: Basic d2ViLXNlcnZpY2UucnU6Y2xpZW50IHNlY3JldA==
Пример зпроса:
POST http://localhost:8080/oauth2/token
Content-Type: application/x-www-form-urlencoded
client_id=YOUR-CLIENT-ID&
client_secret=YOUR-CLIENT-SECRET&
grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&
assertion=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.[сокращенно для краткости].NorYsi-Ht826HUFCEArVZ60_dEUmYiJYXubnTyweIMg