Руководство к использованию стандарта FHIR в ЦИСЗ
0.2.6803 - ci-build
В настоящем руководстве по внедрению описывается набор базовых шаблонов на основе технологии OAuth 2.0 для авторизации, аутентификации и интеграции с программными интерфейсами ЦИСЗ.
Программные интерфейсы ЦИСЗ защищены сервером авторизации с использованием технологии OAuth 2.0.
При каждом вызове методов ЦИСЗ клиентское приложение (МИС ОЗ) должно передавать токен доступа в заголовке запроса. Токен доступа выдаётся клиентскому приложению при его авторизации в ЦИСЗ.
Поддерживаются следующие методы авторизации:
двусторонний метод (Client Credentials) - в этом случае клиентское приложение использует свои учетные данные для получения токена доступа. Токен доступа, полученный по этой схеме, считается токеном организации;
трехсторонний метод (Authorization Code with PKCE) - в этом случае клиентское приложение должно получить авторизацию пользователя для получения токена доступа, помимо своих учетных данных. Этот метод является основным при взаимодействии с ЦИСЗ и токен доступа, полученный по нему, считается токеном медицинского работника.
Примечание: Импорт пакета медицинских данных и доступ к медицинским данным пациента возможны только с токеном медицинского работника.
ЦИСЗ определяет документ обнаружения, доступный по адресу [AUTH_BASE]/.well-known/openid-configuration, позволяя клиентам узнать URL-адреса конечных точек авторизации и функции, поддерживаемые сервером. Эта информация помогает клиенту направлять запросы авторизации на нужную конечную точку и помогает клиентам создавать запросы авторизации, которые может поддерживать сервер.
В дополнение к стандартным областям разрешения приложений (scope), ЦИСЗ поддерживает следующие:
Авторизация по схеме Client Credentials Grant используется для методов программных интерфейсов ЦИСЗ, когда действие должно быть выполнено от имени ОЗ, а не от имени конкретного медицинского работника.
401), необходимо получить новый системный токен, начав сценарий заново.Идентификатор системы и секрет назначаются заранее Оператором ЦИСЗ.
Аутентификация выполняется по протоколу OAuth2.0 с передачей параметра grant_type=client_credentials.
В случае успеха в ответе будет сразу возвращен токен доступа. В случае ошибки ответ будет содержать данные, указывающие на произошедшую ошибку.
POST [AUTH_BASE]/token
Request Headers
Accept: application/json
Content-Type: application/x-www-form-urlencoded
Request Body
grant_type: "client_credentials"
client_id: "[client_id]"
client_secret: "[client_secret]"
scope: "[scope]"
grant_type - метод авторизации клиентского приложения.
В соответствии со спецификацией OAuth 2.0 этот параметр устанавливается равным client_credentials;
client_id - идентификатор клиентского приложения, соответствующий системе, например testclient;
client_secret - секретный ключ (пароль) клиентского приложения, например BuPpC0UK8ohtq5KiwnpW919bmoswQZL0;
scope - область разрешений для клиентского приложения. Возможные значения задаются конфигурацией.
200 OK
Response Body
{
"access_token": "Mfu2RAmbKtY9czFZquSKwA",
"expires_in": 3600,
"refresh_expires_in": 0,
"token_type": "Bearer",
"scope": "iehr_audience"
}
access_token - выданный токен доступа;
expires_in - срок действия токена доступа (в секундах);
refresh_expires_in - срок действия токена обновления (в секундах);
token_type - тип выданного токена доступа. Всегда принимает значение Bearer;
scope - область разрешений для клиентского приложения, возможные значения задаются конфигурацией.
Если при попытке получения токена доступа произошла ошибка, API аутентификации отправляет её код вместе с описанием:
404 Not Found
Response Body
{
"message": "Client not exist in such realm",
"status": 40300004
}
status - код ошибки;
message - описание ошибки.
При каждом вызове методов ЦИСЗ клиентскому приложению (МИС ОЗ) для авторизации в ЦИСЗ необходимо передавать токен доступа в заголовке запроса (Request Headers):
Authorization: Bearer [access_token]
access_token - токен доступа,
полученный в ответе на шаге получения токена.GET [FHIR_BASE]/Patient/dea8c84b-1e61-11ef-9485-57d49cab5591
Request Headers
Accept: application/json
Authorization: Bearer [access_token]
Ответ на успешный запрос:
200 OK
Response Body
{
"resourceType": "Patient",
"id": "dea8c84b-1e61-11ef-9485-57d49cab5591",
......
}
Ответ на запрос без токена доступа, либо с токеном доступа, срок действия которого истёк:
401 Unauthorized
Response Body
{
"resourceType": "OperationOutcome",
"id": "8912817e-fbfa-49d9-b3f5-e75296fcd50e",
"meta": {
"lastUpdated": "2025-01-14T12:24:40.6641168+00:00"
},
"issue": [
{
"severity": "error",
"code": "login",
"diagnostics": "Authentication failed"
}
]
}
Ответ на запрос с токеном доступа к запрещённому ресурсу:
403 Forbidden
Response Body
{
"resourceType": "OperationOutcome",
"id": "8912817e-fbfa-49d9-b3f5-e75296fcd50e",
"meta": {
"lastUpdated": "2025-01-14T12:24:40.6641168+00:00"
},
"issue": [
{
"severity": "error",
"code": "forbidden",
"diagnostics": "Access is denied"
}
]
}
Процесс аутентификации пользователей в ЦИСЗ осуществляется исключительно с помощью Единой системы идентификации физических и юридических лиц (ЕС ИФЮЛ).
Для взаимодействия с ЕС ИФЮЛ на стороне пользователя должна быть установлена Клиентская программа ЕС ИФЮЛ. Установка и настройка Клиентской программы осуществляются в порядке, определенном в руководствах оператора Клиентской программы ЕС ИФЮЛ, с учетом особенностей, описанных на вкладке «Подключение». Указанные документы доступны для скачивания вместе с соответствующим программным обеспечением по ссылке.
В качестве средств строгой аутентификации и средств ЭЦП могут использоваться идентификационные карты, а также иные средства ЭЦП, распространяемые в рамках Государственной системы управления открытыми ключами проверки электронной цифровой подписи Республики Беларусь (ГосСУОК).
Медицинский работник для аутентификации с помощью ЕС ИФЮЛ должен использовать носитель ключевой информации с сертификатом юридического лица ГосСУОК, либо сертификат физического лица и атрибутный сертификат ГосСУОК, определяющий место работы.
В результате аутентификации ЕС ИФЮЛ передает в информационную систему данные о физическом лице (идентификационный номер, фамилию, имя, отчество, место регистрации, атрибутный сертификат с полномочиями пользователя).
Для аутентификации пользователя в ЦИСЗ средствами КПСИС формируется запрос на аутентификацию, содержащий перечень утверждений (scopes), необходимых ЦИСЗ для авторизации пользователя. Запрос подписывается, шифруется и направляется в ЕС ИФЮЛ. ЕС ИФЮЛ выполняет протокол аутентификации с пользователем через Клиентскую программу, запрашивает недостающие сведения в государственных информационных ресурсах через ОАИС, возвращает в ЦИСЗ данные аутентифицированного пользователя.
Клиентская программа предназначена для взаимодействия пользователя с ЕС ИФЮЛ и ЦИСЗ.
Для выполнения аутентификации необходимо направить пользователя на соответствующий адрес с указанием идентификатора клиентского приложения и адреса обратного перенаправления. ЦИСЗ выполнит аутентификацию клиентского приложения, после чего выполнит переход на указанный адрес и передаст при этом код авторизации, который необходим для получения токена доступа.
GET [AUTH_BASE]/auth?client_id=[client_id]&redirect_uri=[redirect_uri]&response_type=code&code_challenge=3VOSAUi7ELIj1HsNe7Cr-v3ylDh5aaG_JvGW-s0brlk&code_challenge_method=S256&scope=[scope]
response_type - тип запрашиваемого разрешения на авторизацию (authorization grant). Необходимо использовать значение code;
client_id - идентификатор клиентского приложения, возможные значения зависят от конфигурации (например testclient);
redirect_uri - адрес (URL) обратного перенаправления (URL-encoded). Например: https://oauth.pstmn.io/v1/callback.
Определяет, на какую страницу пользователь будет перенаправлен после успешной аутентификации. Адрес обратного перенаправления должен присутствовать в списке разрешенных в конфигурации аутентификации клиента, список разрешенных адресов конфигурируется администратором;
code_challenge - хэш-значение случайной строки (code_verifier) в кодировке BASE64. Случайная строка code_verifier используется для получения токена доступа. Длина строки code_verifier должна быть минимум 32 байта и при каждом запросе на авторизацию необходимо использовать новое значение;
code_challenge_method - алгоритм вычисления хеш-значения параметра code_verifier. Необходимо использовать значение S256;
state - параметр задается на стороне клиентского приложения, представляет собой любую комбинацию символов. Используется для улучшения безопасности. Приложение должно проверить, что выходящее значение state будет равно тому, что пришло на заключительном этапе вместе с токеном доступа. Параметр является необязательным;
scope - область разрешений для клиентского приложения. Возможные значения задаются конфигурацией (например, session_max_idle_time, client_organization).
Аутентифицированный пользователь будет перенаправлен на redirect_uri, указанный в запросе, с кодом авторизации в GET-параметре.
GET [redirect_uri]?code=[auth_code]&state=[state]
redirect_uri - URL-адрес обратного перенаправления, например: https://oauth.pstmn.io/v1/callback;
code - код авторизации, например: 1d601e9a-992d-44a7-be21-bca07fbc762c;
state - дополнительные данные, которые были переданы в начале аутентификации в параметре state (если параметр state не указывался, то он будет отсутствовать и в конечном URL, на который происходит перенаправление).
Для получения данных пользователя и возможности выполнять действия от его имени клиентское приложение должно получить access token. Для этого нужно выполнить запрос на соответствующий URL API аутентификации с указанием данных клиентского приложения и кода авторизации, полученного после аутентификации.
POST [AUTH_BASE]/token
Request Headers
Accept: application/json
Content-Type: application/x-www-form-urlencoded
Request Body
client_id: "[client_id]"
redirect_uri: "[redirect_uri]"
grant_type: "authorization_code"
code_verifier: "[code_verifier]"
code: "[auth_code]"
client_id - идентификатор клиентского приложения, возможные значения зависят от конфигурации (например testclient);
redirect_uri - URL обратного перенаправления, который был указан при аутентификации (URL encoded). Например: https://oauth.pstmn.io/v1/callback;
grant_type - способ получения access token. В сценарии получения access token по коду авторизации всегда используется значение authorization_code;
code_verifier - строка, от которой было вычислено хэш-значение, указанное в параметре code_challenge запроса на аутентификацию клиентского приложения;
code - код авторизации, полученный после аутентификации. Например: 1d601e9a-992d-44a7-be21-bca07fbc762c.
200 OK
Response Body
{
"access_token":"eyJhbGciOiJSUzrdguug",
"expires_in":3600,
"refresh_expires_in":14969,
"refresh_token":"EjJgNiNmYl4gv9kYeJDslCc76ySWz3yqOdKc4MmgIS17jo3pEuM4KDFUQ",
"token_type":"Bearer",
"scope":"iehr_audience"
}
access_token - выданный токен доступа;
expires_in - срок действия токена доступа (в секундах);
refresh_expires_in - срок действия токена обновления (в секундах);
refresh_token - токен обновления. Может быть использован для получения нового токена доступа без повторной аутентификации;
token_type - тип выданного токена доступа. Всегда принимает значение Bearer;
scope - область разрешений для клиентского приложения. Возможные значения задаются конфигурацией.
При каждом вызове методов ЦИСЗ клиентскому приложению (МИС ОЗ) для авторизации в ЦИСЗ пользователя необходимо передавать токен доступа в заголовке запроса (Request Headers):
Authorization: Bearer [access_token]
access_token - токен доступа, полученный в ответе на шаге получения токена.GET [FHIR_BASE]/Patient/dea8c84b-1e61-11ef-9485-57d49cab5591
Request Headers
Accept: application/json
Authorization: Bearer [access_token]
Ответ на успешный запрос:
200 OK
Response Body
{
"resourceType": "Patient",
"id": "dea8c84b-1e61-11ef-9485-57d49cab5591",
......
}
Ответ на запрос без токена доступа, либо с токеном доступа, срок действия которого истёк:
401 Unauthorized
Response Body
{
"resourceType": "OperationOutcome",
"id": "8912817e-fbfa-49d9-b3f5-e75296fcd50e",
"meta": {
"lastUpdated": "2025-01-14T12:24:40.6641168+00:00"
},
"issue": [
{
"severity": "error",
"code": "login",
"diagnostics": "Authentication failed"
}
]
}
Ответ на запрос с токеном доступа к запрещённому ресурсу:
403 Forbidden
Response Body
{
"resourceType": "OperationOutcome",
"id": "8912817e-fbfa-49d9-b3f5-e75296fcd50e",
"meta": {
"lastUpdated": "2025-01-14T12:24:40.6641168+00:00"
},
"issue": [
{
"severity": "error",
"code": "forbidden",
"diagnostics": "Access is denied"
}
]
}
POST [AUTH_BASE]/token
Request Headers
Accept: application/json
Content-Type: application/x-www-form-urlencoded
Request Body
grant_type: "refresh_token"
refresh_token: "[refresh_token]"
grant_type - способ получения access token. В сценарии получения access token по токену обновления всегда используется значение refresh_token;
refresh_token - токен обновления, выданный ранее вместе с токеном доступа. Например: d5e0ccfe-501e-4740-8708-a45fa5d369ce.
Глобальный выход из сервиса аутентификации ЦИСЗ может быть осуществлен путем перехода аутентифицированного пользователя на URL: [AUTH_BASE]/logout.
Рекомендуется добавить в URL параметр post_logout_redirect_uri с адресом обратного перехода, на этот адрес пользователь будет перенаправлен сразу после выхода.
GET [AUTH_BASE]/logout?token=[token]&token_type_hint=refresh_token&client_id=[client_id]&post_logout_redirect_uri=[post_logout_redirect_uri]
client_id - идентификатор клиентского приложения, возможные значения зависят от конфигурации (например: testclient);
token_type_hint - тип передаваемого токена доступа, всегда refresh_token;
token - ранее выданный токен обновления. Например: eyJhbGciOiJIU5cCI6IkpXVCJ9.eyJzyMn0.KMUFsIDTnFm;
post_logout_redirect_uri - URL-адрес обратного перенаправления (URL-encoded). Например: https://oauth.pstmn.io/v1/callback. Адрес обратного перенаправления должен присутствовать в списке разрешенных в конфигурации аутентификации клиента, список разрешенных адресов конфигурируется администратором.
Описание полей в токене доступа
{
"exp": 1770105185,
"iat": 1770101585,
"iss": "https://internal.cisz.by/auth/api/realms/iehr",
"unp": "193605729",
"practitioner_id": "a0083f86-0891-11f0-ab4f-0498b5b97a51",
"organization_id": "14736518-cc34-4e2e-8d60-204955589577",
"department_ids": [
"14736518-cc34-4e2e-8d60-204955589577",
"23536342-cc44-3f5e-2d80-333123589123",
],
// other fields
}
При выполнении операцими $import custodian в Composition должен содержать department_id из токена
"custodian":{
"reference":"Organization/[one of department_ids]"
}
При выполнении операцими $import author в Composition должен содержать practitioner_id из токена
"author":[
{
"reference":"Practitioner/[practitioner_id]"
}
]
Пример Bundle:
{
"id":"BundleId",
"meta":{
"profile":[
"https://fhir.by/AbstractArea/StructureDefinition/Bundle/MedicationDocument"
]
},
"resourceType":"Bundle",
"timestamp":"2024-04-07T11:12:21Z",
"type":"document",
"entry":[
{
"id":"d73767af-3c71-47b1-88a6-59aea621f766",
"meta":{
"profile":[
"https://fhir.by/StructureDefinition/CompDocument"
]
},
"resourceType":"Composition",
"fullUrl":"Composition/CompositionFullBundle",
"resource":{
"author":[
{
"reference":"Practitioner/a0083f86-0891-11f0-ab4f-0498b5b97a51" // practitioner_id
}
],
"custodian":{
"reference":"Organization/14736518-cc34-4e2e-8d60-204955589577" // department_ids
}
}
}
]
}
Важно
organization_id и department_ids будут иметь одинаковые значения для Организации (юр. лица), если медработник является сотрудником этой организации;organization_id и department_ids будут иметь разные значения у медработника, который принят на работу в конкретный филиал, но не является сотрудником головной организации;department_ids может иметь несколько значений и содержать одинаковые или отличные от головной организации organization_id и department_ids.department_ids должен совпадать с идентификатором организации в Composition.custodian при импорте медицинских данных.
При вызове операций, для которых выполняется проверка идентификатора организации (например, $set-status) в токене доступа медицинского работника должен содержаться тот же идентификатор, который содержится в ресурсах, над которыми выполняется операция.
Пример: выполнение операции $set-status для ресурса ServiceRequest.
department_ids из Authorization: Bearer [access_token] должен совпадать с идентификатором организации в ресурсе ServiceRequest, или в элементе ServiceRequest.persoformer или ServiceRequest.extension:fromOrganization.