Параметр способа аутентификации authentication.method должен быть также установлен на клиентской части приложения в app-config.json
Также для аутентификации по сертификату нужны свойства для хранилища сертификатов:
- certificate.keystore.location - путь до java key store. Key store - это хранилище доверенных сертификатов, с помощью которых можно проверить корневой сертификат. Сертификат устанавливается с помощью команды:
Получите от администратора Kerberos .keytab файл, из которого командой `klist -k http.keytab` можно получить список principal-ов
Проверить успешность авторизации principal-а можно командой `kinit -t -i http.keytab %principal%`.
В
случае успешной авторизации команда `klist` в качестве default principal которым проводилась авторизация.
После этого в standalone.xml поправить параметр `app.service-principal` на principal, которым успешно авторизовались. principal имеет формат: `HTTP/%hostname%@%REALM%`
#### Настройка сервера приложений для работы с Kerberos
1. создать учетные записи в домене:
- тестовые для проверки работоспособности функционала (пользователи домена, почтовые ящики):
`User1 pass1 user1@example.com`
`User2 pass2 user2@example.com`
- сервисную для доступа сервиса(приложения) к MS AD - (пользователь домена - снять устаревание пароля, ограничение по времени действия, почтовый ящик):
`serviceUser servicePass serviceuser@example.com`
---
2. завести учетную запись машины `appserver.machine.name` (fqdn-имя сервиса) в AD (вручную, как запись в computer) и в DNS (A-запись)
`appserver.machine.name 10.250.216.91`
3. сгенерировать keytab (утилита ktpass) для аутентификации сервисов(приложения) для единой точки входа - `serviceUser` - с именем test.file.name.keytab - привязав к ней пользователя serviceUser
-В случае, если авторизация не проходит и в логах сервера приложений присутствует следующий вывод:
```
2019-05-14 05:33:36,588 INFO [security.controller.KerberosAuthenticationController] (default task-3) Authentication request header Authorization not exists
2019-05-14 05:33:36,588 INFO [security.controller.KerberosAuthenticationController] (default task-3) Authentication object is not presented
```
необходимо проверить настройку браузера firefox `network.negotiate-auth.trusted-uris`, она должна соответствовать домену из principal-а.
Для этого в поисковую строку браузера вводим "about:config", в открывшемся окне нажимаем "accept with risk and continue", в поисковой строке открывшейся страницы ввести `network.negotiate-auth.trusted-uris`.
Пример: для principal-а`HTTP/oleg-rxserver.alt.dom@ALT.DOM` настройка в браузере должна быть `.alt.dom`, приложение в браузере должно открываться по `http:\\oleg-rxserver.alt.dom:8080\...`
- если в логах сервера приложений есть ошибка:
```xml
2019-05-13 14:13:07,095 WARN [org.springframework.security.kerberos.web.authentication.SpnegoAuthenticationProcessingFilter] (default task-1) Negotiate Header was invalid: Negotiate TlRMTVNTUAABAAAAl4II4gAAAAAAAAAAAAAAAAAAAAAKAGNFAAAADw==: org.springframework.security.authentication.BadCredentialsException: Kerberos validation not successful
...
Caused by: java.security.PrivilegedActionException: GSSException: Defective token detected (Mechanism level: GSSHeader did not find the right tag)
at java.security.AccessController.doPrivileged(Native Method) [rt.jar:1.8.0_211]
at javax.security.auth.Subject.doAs(Subject.java:422) [rt.jar:1.8.0_211]
at org.springframework.security.kerberos.authentication.sun.SunJaasKerberosTicketValidator.validateTicket(SunJaasKerberosTicketValidator.java:68) [spring-security-kerberos-core-1.0.1.RELEASE.jar:1.0.1.RELEASE]
... 66 more
Caused by: GSSException: Defective token detected (Mechanism level: GSSHeader did not find the right tag)
at sun.security.jgss.GSSHeader.(GSSHeader.java:97) [rt.jar:1.8.0_211]
at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:306) [rt.jar:1.8.0_211]
at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:285) [rt.jar:1.8.0_211]
at org.springframework.security.kerberos.authentication.sun.SunJaasKerberosTicketValidatorKerberosValidateAction.run(SunJaasKerberosTicketValidator.java:170) [spring-security-kerberos-core-1.0.1.RELEASE.jar:1.0.1.RELEASE]
at org.springframework.security.kerberos.authentication.sun.SunJaasKerberosTicketValidatorKerberosValidateAction.run(SunJaasKerberosTicketValidator.java:153) [spring-security-kerberos-core-1.0.1.RELEASE.jar:1.0.1.RELEASE]
... 69 more
```
необходимо проверить правильность указанного в standalone.xml principal-а.
### Комбинации нескольких способов аутентификации
Приложение может обрабатывать запросы на несколько способов аутентификации. Для этого необходимо переичислить нужные профили через запятую.
`webbpm.security.access_token.duration.minutes` - опциональный параметр (значение по умолчанию 60), время жизни в минутах, сколько будет действителен токен, после истечения этого времени токен будет обновлён `webbpm.security.refresh_token.duration.days` - опциональный параметр (значение по умолчанию 30), время жизни в днях, после истечения этого времени с последнего обновления, пользователю будет необходимо повторно войти `webbpm.security.session.active.count` - опциональный параметр (значение по умолчанию 1), количество сохраняемых в базу токенов обновления (количество активных сессий)
Примечания.
- Нельзя использовать одновременно профили cert_over_db c cert_over_ldap и kerberos с form.
-`webbpm.db.query_limit_enabled` - флаг, отвечающий за вывод сообщений о превышении лимитов на количество возвращаемых записей. По умолчанию - false.
-`webbpm.db.select_records_max_limit` - максимальный лимит возвращаемых строк для запросов в БД, при превышении/равенстве данного лимита будет выброшена ошибка (*целое числовое значение*). По умолчанию - 100000
-`webbpm.db.select_records_min_limit` - минимальный лимит возвращаемых строк для запросов в БД, при превышении/равенстве данного лимита в логи будет выведен warning (*целое числовое значение*). По умолчанию - 1000
-`webbpm.db.execution_time_threshold`. The threshold for time of executing a statement. Система выводит сообщение в логи при превышении. Действует для запросов, созданных в jOOQ. По умолчанию - 1000 миллисекунд
-`webbpm.db.result_read_time_threshold`. The threshold for time of fetching a set of records from a ResultSet.
. Система выводит сообщение в логи при превышении. Действует для запросов, созданных в jOOQ. По умолчанию - 50 миллисекунд
-`webbpm.db.results_count_threshold`. Система выводит сообщение в логи при превышении. Действует для запросов, созданных в jOOQ. По умолчанию - 1000 записей
-`webbpm.db.full_time_threshold`. Ограничение на полное время выполнения запроса. Система выводит сообщение в логи при превышении. Действует для запросов, созданных в jOOQ. По умолчанию sum(webbpm.db.result_read_time_threshold, webbpm.db.execution_time_threshold) миллисекунд
-`webbpm.db.query_timeout`. Ограничение на время выполнения запроса. При превышении запрос будет отклонен. Действует для запросов, созданных в jOOQ в dev режиме. По умолчанию 120 секунд.
Почтовый сервер - зарегистрированный актуальный почтовый адрес. В поле password нужно указывать не пароль для входа в почту, а создать пароль для приложений в учетке почты и указать его.
2. Для включения регистрации добавьте в *standalone.xml* свойство
#### Настройка браузера для входа в систему с помощью Kerberos
1. Запустите браузер firefox.
2.В адресной строке введите about:config, нажать кнопку "я принимаю на себя риск"
3.С помощью поиска найдите параметр network.negotiate-auth.trusted-uris и в качестве значения ввести домен(например для домена example.com надо ввести .example.com)
4. Откройте в браузере приложение. Пример [http://app.example.com/](http://app.example.com/) . Приложение должно открыться без запроса логина/пароля
## Восстановление структуры БД
На основе БД проекта с помощью jOOQ генерируются Java классы для каждого объекта БД. Это происходит по нажатию кнопки Обновить на панели БД в студии. При необходимости можно сформировать DDL на основе данных классов. Пример класса для генерации DDL
```
package ru.cg.webbpm.test_project.db_beans;
import org.jooq.*;
import org.jooq.impl.*;
public class Main {
public static void main (String args []) {
DefaultConfiguration defaultConfiguration = new DefaultConfiguration();
-`webbpm.cache.hazelcast.kubernetes.service_name` - имя сервиса в среде kubernetes,
используемый для обнаружения других подов. Подходит как стратегия обнаружения, если используется
kubernetes
-`webbpm.cache.hazelcast.outbound_port_definitions` - исходящие порты hazelcast. по дефолту не задано, система сама выбирает свободные порты. Задать диапазон 5801 - 5820
-`webbpm.cache.hazelcast.backup_count`. Нужны чтобы когда сервер выключается был доступен бекап. Если предполагается выключать несколько серверов за раз, то нужно увеличить.
Данный бекап делает копии синхронно с основной записью и операция записи ждет пока будет записана везде. Можно делать бекап асинхронно, настраивается через async_backup_count
подробнее про бекапы [Hazelcast IMDG Reference Manual](https://docs.hazelcast.org/docs/3.11/manual/html-single/index.html#backing-up-maps) . по дефолту 1
## Подключение компоненты адреса в режиме ГАР (Государственный адресный реестр)
Необходимо задать параметры:
-`gar.enable` - флаг, который включает/отключает сервис для работы с ГАР. Должен быть задан для работы компоненты в режиме ГАР. По умолчанию true, для отключения задать false.
-`gar.elastic.url.host` - хост на котором развернут elasticsearch.
-`gar.elastic.password` - пароль для аутентификации elasticsearch.
Дополнительные параметры:
-`gar.elastic.url.port` - порт на котором развернут elasticsearch.
-`gar.elastic.username` - логин для аутентификации elasticsearch.
Отчет собирается раз в 30 секунд по дефолту, меняется параметром `webbpm.metrics.report_period_ms`.
Все метрики идут за отчетный период, после сбора отчета они сбрасываются.
Получить json со всеми метриками можно по урлу `backend/metrics/v1/all` - метрики будут с последнего собранного отчета, запрос не триггерит сбор отчета - это независимые операции. Отчет содержит только метрики по которым был совершен хотя бы один вызов в отчетный период. То есть, если какая-то операция не была совершена в отчетный период, то соответствующая ей метрика не попадет в отчет - ее не будет в json.
### Значения метрик
Все метрики идут за отчетный период, после сбора отчета они сбрасываются.
Нас в основном интересуют `callsCountSum`, `latencyMin`, `latencyAvg`, `latencyMax`
-`callsCountSum` - количество завершенных вызовов
-`latencyMin` - минимальное время выполнения
-`latencyAvg` - среднее время выполнения
-`latencyMax` - максимальное время выполнения
-`activeCallsCountMax` - количество начатых, но еще не завершенных вызовов.
-`activeCallsLatencyMax` - длительность самого долгого еще не завершенного вызова
### Текущие метрики приложения
- Получение коннекта из пула
-`webbpm.jbpm.db.connection.acquire`
-`webbpm.security.db.connection.acquire`
-`webbpm.db.connection.acquire`
- Время с момента получения коннекта до возврата его в пул
-`webbpm.jbpm.db.connection.in_use`
-`webbpm.security.db.connection.in_use`
-`webbpm.db.connection.in_use`
- Время выполнения запроса на бд проекта
-`webbpm.db.query.success.execution_time`
- Время выполнения запроса на бд проекта + время получения коннекта из пула
-`webbpm.db.query.success.full_time`
- active-users-count.indicatorMax
- active-users-count-ttl.indicatorMax
# Количество пользователей
-`webbpm.active_users_counter.enabled` - включает подсчет пользователей, нужно чтобы не запускать hazelcast на дев машинах. по дефолту false. На боевых серверах необходимо установить в true.
-`webbpm.active_users_counter.max_time_between_operations_in_seconds` - время, которое пользователь считается активным после действия. по дефолту 15 минут.
-`webbpm.active_users_counter.hazelcast.app_pool_size`. Запись в hazelcast производится асинхронно в отдельном пуле, не блокируя обработку http запроса. Это размер этого пула. по дефолту 4. Можно пока оставить 4 и последить за метриками pool.hazelcast-executor.queue.indicatorMax и pool.hazelcast-executor.activeThreads.indicatorMax. Если очередь будет сильно копиться, то увеличить.
## Настройка логов
Все настройки делаются в файле `standalone.xml`, если не указано иначе.
### Общие настройки
Платформа Web-bpm использует корневую категорию логирования `ru.cg.webbpm`, рекомендуется выставлять ее в уровень `info`. todo check prod config
```xml
<loggercategory="ru.cg.webbpm">
<levelname="INFO"/>
</logger>
```
При этом компоненты используемые в проекте могут использовать другие категории.
### Параметры конфигурации
**Рекомендованное использование:** всегда в `info`.
Все параметры конфигурации загружаемые платформой web-bpm и пользовательским приложением через api webbpm логируются категорией `ru.cg.webbpm.modules.core.app_info.api.property.BaseProperty`. Она всегда должна быть выставлена в `info`.
Пример вывода:
```
2017-12-04 16:02:19,074 INFO [ru.cg.webbpm.modules.core.app_info.api.property.BaseProperty] (EclipseGeminiBlueprintExtenderThread-1) System property [webbpm.active_users_counter.enabled] not set. Using default value [false]
2017-12-04 16:02:19,074 INFO [ru.cg.webbpm.modules.core.app_info.api.property.BaseProperty] (EclipseGeminiBlueprintExtenderThread-1) System property [webbpm.active_users_counter.hazelcast.hosts] set to [127.0.0.1]
```
### БД проекта
#### Логирование запросов в бд security и бд проекта
**Рекомендованное использование:** только при разработке.
Использовать только при разработке. Категория `org.jooq.tools.LoggerListener` в `debug` уровень.
```xml
<loggercategory="org.jooq.tools.LoggerListener">
<levelname="DEBUG"/>
</logger>
```
Пример вывода:
```
2017-12-04 18:21:10,391 DEBUG [org.jooq.tools.LoggerListener] (default task-19) Executing query : select "department"."department_name", "department"."department_id", "department"."parent_department_id", "department"."parent_department_id", "department"."department_id", (select (count(*) <> ?) from "public"."department" as "$$child" where "$$child"."parent_department_id" = "department"."department_id") as "$$hasChildren" from "public"."department" as "department" limit ?
2017-12-04 18:21:10,395 DEBUG [org.jooq.tools.LoggerListener] (default task-19) -> with bind values : select "department"."department_name", "department"."department_id", "department"."parent_department_id", "department"."parent_department_id", "department"."department_id", (select (count(*) <> 0) from "public"."department" as "$$child" where "$$child"."parent_department_id" = "department"."department_id") as "$$hasChildren" from "public"."department" as "department" limit 2147483647
2017-12-04 18:21:10,568 DEBUG [org.jooq.tools.LoggerListener] (default task-19) Fetched result : +-----------------+-------------+--------------------+--------------------+-------------+-------------+
**Рекомендованное использование:** всегда в `info`, с подобранными для проекта значениями. В проде значения должны быть проверены что они не вызывают излишнее логирование.
1. Для отслеживания больших запросов в пользовательскую базу нужно задать параметры что считать большими запросами, логироваться будут запросы больше заданных показателей.
Чтобы логировать все запросы можно задать значение `-1`. Добавляются как property в раздел `system-properties`:
-`webbpm.db.full_time_threshold` - полное время выполнения запроса в миллисекундах. Включает построение запроса библиотекой, выполнение и загрузку результатов. Пример сообщения <br>`2023-01-11 13:09:38,361 WARN [ru.cg.webbpm.modules.database.impl.analytics.PerformanceListener] (default task-33) Query full time threshold exceeded. full_time=[6565ms] execution_time=[6565ms] read_time=[0ms] results_count=[4] query=[<your query>]`
-`webbpm.db.results_count_threshold` - количество записей, которое вернул запрос. Пример сообщения <br>`2023-01-11 13:10:34,088 WARN [ru.cg.webbpm.modules.database.impl.analytics.PerformanceListener] (default task-41) Query results count threshold exceeded. results_count=[11177] query=[<your query>]`
В`debug` режиме дополнительно к работающим в info:
-`webbpm.db.execution_time_threshold` - время выполнения запроса + построения запроса библиотекой.
-`webbpm.db.result_read_time_threshold` - время чтения результатов запроса
2. После задания настроек нужно настроить логирование - категория `ru.cg.webbpm.modules.database.impl.analytics.PerformanceListener`, уровень `info` или `debug`.
18:21:06,938 DEBUG [org.hibernate.SQL] (default task-47) select names0_.Task_Names_Id as Task_Nam7_16_0_, names0_.id as id1_16_0_, names0_.id as id1_16_1_, names0_.language as language2_16_1_, names0_.shortText as shortTex3_16_1_, names0_.text as text4_16_1_ from I18NText names0_ where names0_.Task_Names_Id=?
**Рекомендованное использование:** только при разработке в случае необходимости.
1. Время выполнения запроса и количество результатов.
Включаются категорией `org.hibernate.stat` в `debug`. При этом в hibernate должен быть включен сбор статистики.
Похоже что логируется только hql select запросов.
```xml
<loggercategory="org.hibernate.stat">
<levelname="DEBUG"/>
</logger>
```
Пример вывода:
```
18:21:06,858 DEBUG [org.hibernate.stat.internal.ConcurrentStatisticsImpl] (default task-41) HHH000117: HQL: select t from AuditTaskImpl t where t.taskId = :taskId, time: 6ms, rows: 1
```
2. Показатели hibernate сессий
Включаются категорией `org.hibernate.engine.internal.StatisticalLoggingSessionEventListener` в `info`.
При этом в hibernate должен быть включен сбор статистики. Тут может быть интересно количество запросов, флашей и общее время на все запросы сессией.
Пример вывода:
```
2017-12-04 17:25:58,493 INFO [org.hibernate.engine.internal.StatisticalLoggingSessionEventListener] (default task-21) Session Metrics {
297556 nanoseconds spent executing 1 flushes (flushing a total of 16 entities and 0 collections);
430168 nanoseconds spent executing 1 partial-flushes (flushing a total of 16 entities and 16 collections)
}
```
#### Логирование hbm2ddl
**Рекомендованное использование:** всегда в `trace`.
Должно быть включено всегда. Позволяет убедиться что hibernate не накатывал никакие миграции на базу. Этот функционал отключен у нас в коде.
```xml
<loggercategory="org.hibernate.tool.hbm2ddl">
<levelname="TRACE"/>
</logger>
```
# Описание параметров конфигурации клиентской части
Свойства задаются в файле frontend/src/resources/app-config.json или frontend.war/src/resources/app-config.json
## Общие
-`dev_mode` - настройка задающая dev_mode для просмотра логов (true/false). При отсутствие оставляет значение при сборке
-`guard.confirm_exit` - выводить или нет диалог подтверждения, если обнаружены несохраненные данные в форме. Значение по умолчанию - false.
-`password.pattern` - Регулярное выражение для валидации пароля.
-`password_pattern_error` - Сообщение об ошибке валидации.
-`show.client.errors` - отвечает за отображение ошибок javascript-a пользователю (должна использоваться только в тестовых контурах) по умолчанию выключена
- 'available_task.single_fetch' - Отвечает за количество запросов available_task при завершении процесса. true - одиночный запрос, false/не указано - 10 запросов(старая реализация).
## Вывод сообщений
-`message_service_error_timeout` время в мс, в течение которого будет отображено сообщение об ошибке. Значение по умолчанию - таймаут не задан (окно не закрывается).
-`message_service_warning_timeout` время в мс, в течение которого будет отображено предупреждающее сообщение. Значение по умолчанию - таймаут не задан (окно не закрывается).
-`message_service_success_timeout` время в мс, в течение которого будет отображено сообщение об успехе. Значение по умолчанию - таймаут не задан (окно не закрывается).
-`message_service_info_timeout` время в мс, в течение которого будет отображено информационное сообщение. Значение по умолчанию - таймаут не задан (окно не закрывается).
## Электронная подпись
### Esmart
-`electronic_sign.esmart_extension_url` - url для создания расширенной подписи. Подробная информация по ссылке [http://demo.esmart.ru](http://demo.esmart.ru)
-`electronic_sign.tsp_address` - адрес сервера службы штампов времени
#### Взаимодействие с ЕСНСИ в части получения справочника ОКОПФ
-`ESNSI_OKOPF_URL` - url который обращается к еснси для получения справочника и скачивает данные спровочников организации в виде заархивированного json файла.
-`ERVU_FILE_UPLOAD_MAX_FILE_SIZE` - определяет максимальный размер загружаемого файла в байтах. Указывает предел размера для каждого индивидуального файла, который может быть загружен. Если файл превышает этот размер, загрузка будет прервана, и может быть вызвано исключение.
-`ERVU_FILE_UPLOAD_MAX_REQUEST_SIZE` - устанавливает максимальный общий размер всех файлов в одном многозадачном запросе в байтах. Это ограничение на весь запрос, включающий данные и файлы. Если общий размер запроса превышает этот параметр, загрузка файлов будет остановлена.
-`ERVU_FILE_UPLOAD_FILE_SIZE_THRESHOLD` - указывает размер (в байтах), при достижении которого файл будет записан во временное хранилище на диск. Это позволяет улучшить производительность, исключая непосредственную запись мелких файлов на диск, если они не превышают указанного порога. Файлы, меньшие этого значения, могут быть сохранены в памяти.
-`FILE_WEBDAV_UPLOAD_URL` - url для подключения к WebDav
-`FILE_WEBDAV_UPLOAD_USERNAME` - логин пользователя для подключения к WebDav
-`FILE_WEBDAV_UPLOAD_PASSWORD` - пароль пользователя для подключения к WebDav
-`AV_KAFKA_BOOTSTRAP_SERVERS` - список пар хост:порт, использующихся для установки первоначального соединения с кластером Kafka
-`AV_KAFKA_SECURITY_PROTOCOL` - протокол, используемый для взаимодействия с брокерами
-`AV_KAFKA_SASL_MECHANISM` - механизм SASL, используемый для клиентских подключений
-`AV_KAFKA_USERNAME` - пользователь для подключения к Kafka
-`AV_KAFKA_PASSWORD` - пароль для подключения к Kafka
-`AV_KAFKA_GROUP_ID` - идентификатор группы потребителей, который отвечает за создание группы для объединения нескольких потребителей
-`AV_KAFKA_MESSAGE_TOPIC_NAME` - топик для записи данных по файлу для перекладчика.
-`AV_KAFKA_DOWNLOAD_RESPONSE` - топик для чтения статусов файла, полученных от перекладчика.
#### Взаимодействие с Kafka ERVU
-`ERVU_KAFKA_BOOTSTRAP_SERVERS` - список пар хост:порт, использующихся для установки первоначального соединения с кластером Kafka
-`ERVU_KAFKA_SECURITY_PROTOCOL` - протокол, используемый для взаимодействия с брокерами
-`ERVU_KAFKA_SASL_MECHANISM` - механизм SASL, используемый для клиентских подключений
-`ERVU_KAFKA_USERNAME` - пользователь для подключения к Kafka
-`ERVU_KAFKA_PASSWORD` - пароль для подключения к Kafka
-`ERVU_KAFKA_GROUP_ID` - идентификатор группы потребителей, который отвечает за создание группы для объединения нескольких потребителей
-`ERVU_KAFKA_REPLY_TIMEOUT` - определяет, сколько времени Kafka будет ожидать ответа от потребителя после отправки сообщения. Значение задается в секундах
-`ERVU_KAFKA_ORG_REQUEST_TOPIC` - топик для записи данных об организации, для получения id организации из ЕРВУ.
-`ERVU_KAFKA_ORG_REPLY_TOPIC` - топик для чтения id организации из ЕРВУ.
-`ERVU_KAFKA_JOURNAL_REQUEST_TOPIC` - топик для записи запроса для получения данных по журналу взаимодействия
-`ERVU_KAFKA_JOURNAL_REPLY_TOPIC` - топик для чтения данных по журналу взаимодействия
-`ERVU_KAFKA_EXCERPT_REQUEST_TOPIC` - топик для записи запроса для получения выписки по журналу взаимодействия
-`ERVU_KAFKA_EXCERPT_REPLY_TOPIC` - топик для чтения выписки по журналу взаимодействия. Содержит ссылку на S3 с файлом выписки