WSO2 Micro Integrator - вызов REST сервиса с Basic Auth
Блоги
Навигационные полоски
В недавнем прошлом была относительно небольшая и простая задача - вызов REST сервиса из WSO2 MI 4.0. Этот сервис был прикрыт при помощи Basic Auth. Для подобных вещей в Apache Synapse можно использовать handlers - это вполне удобно, пользователей можно добавить прямо в локальное хранилище. Так и было сделано:
<?xml version="1.0" encoding="UTF-8"?>
<api context="/rest/api" name="processApi" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="POST" protocol="https" uri-template="/process">
<inSequence>
<log level="custom" separator="
">
<property name="START" value="request POST /rest/api/process"/>
<property expression="get-property('axis2', 'REMOTE_ADDR')" name="client_ip"/>
<property expression="$trp:X-Forwarded-For" name="X-Forwarded-For value"/>
</log>
<sequence key="process"/>
<property description="HTTP_SC" name="HTTP_SC" scope="axis2" type="STRING" value="200"/>
<header action="remove" description="remove Authorization" name="Authorization" scope="transport"/>
<log level="custom" separator="
">
<property name="END" value="request POST /rest/api/process"/>
</log>
<respond/>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
<handlers>
<handler class="org.wso2.micro.integrator.security.handler.RESTBasicAuthHandler"/>
</handlers>
</api>
Задеплоили, проверяем - работает.
Но тестировщик не дремлет и проверяет данный сервис по крайним значениям:
отправляет в сервис пустой запрос, запрос > 60КБ…
Всё отработало… идём дальше.
И вот, при проверке Basic аутентификации с payload > 60КБ и не верными учётными данными сервис уходит в долгое раздумье.
Пришло время дебага!
В логах обнаруживается WARNING по истечении Socket таймаута, кричащий что за 180 секунд сервер не успел считать тело запроса.
Выкручивая все логи в дебаг видим, что входящий http поток остановил чтение на позиции 16384 байт… где-то я видел эту цифру...
После чего сразу подготавливается вывод:
и далее
Варианты решения:
1. Можно в deployment.toml повысить ту самую цифру 16384 до максимального значения размера сообщения, заданного по умолчанию, 81920
[transport.http]
io_buffer_size=16384 → 81920
но WSO2 не рекомендуют заниматься таким тюнингом.
В общем вариант, но не вариант)
2.1. Заглядываем в RESTBasicAuthHandler и ничего криминального там не видим,
но как раз тут поток перенаправляется назад в случае не успешной аутентификации.
org.apache.axis2.context.MessageContext axis2MessageContext
= ((Axis2MessageContext) messageContext).getAxis2MessageContext();
Object headers = axis2MessageContext.getProperty(
org.apache.axis2.context.MessageContext.TRANSPORT_HEADERS);
if (headers != null && headers instanceof Map) {
Map headersMap = (Map) headers;
if (headersMap.get(HTTPConstants.HEADER_AUTHORIZATION) == null) {
log.error(AUTH_FAILED_MESSAGE + HTTPConstants.HEADER_AUTHORIZATION + " header does not exist.");
messageContext.getEnvelope();
log.info( messageContext.getEnvelope());
log.info( messageContext.getMessageString());
headersMap.clear();
axis2MessageContext.setProperty(BasicAuthConstants.HTTP_STATUS_CODE, BasicAuthConstants.SC_UNAUTHORIZED);
headersMap.put(BasicAuthConstants.WWW_AUTHENTICATE, BasicAuthConstants.WWW_AUTH_METHOD);
axis2MessageContext.setProperty(BasicAuthConstants.NO_ENTITY_BODY, true);
messageContext.setProperty(BasicAuthConstants.RESPONSE, BasicAuthConstants.TRUE);
messageContext.setTo(null);
Axis2Sender.sendBack(messageContext);
return false;
...
}
Получается, для решения проблемы, надо вычитать тело запроса до отправки ответа.
С помощью чудо утилиты RelayUtils из артефакта synapse-nhttp-transport мы собираем сообщение из входящего потока.
// build input message
try {
RelayUtils.buildMessage(((Axis2MessageContext) messageContext).getAxis2MessageContext());
} catch (IOException | XMLStreamException e) {
log.error(e);
}
// read the body
log.debug(messageContext.getEnvelope().getBody());
Тело обязательно надо получить messageContext.getEnvelope().getBody() иначе процесс так и не закончится до отправки ответа.
2.2 Либо вместо messageContext.getEnvelope().getBody() можно добавить в параметры запуска для Micro integrator:
-Dforce.json.message.validation="true" -Dforce.xml.message.validation="true"
при таких параметрах в RelayUtils.buildMessage тело полностью вычитывается для валидации.
Имплементируем свой Custom Handler на основе RESTBasicAuthHandler с описанными выше
изменениями. Прописываем в API и получаем результат.
<handlers>
<handler class="ru.emdev.wso2.BasicAuthHandler"/>
</handlers>
* Картинка для статьи взята http://guywithtech.blogspot.com/2020/12/
- 6.2 (12)
- 7.0 (12)
- activiti (14)
- apache camel (6)
- camel (11)
- devcon (6)
- devops (5)
- emdev (9)
- emdev limited (9)
- entaxy (13)
- esb (10)
- fuse (5)
- gartner (7)
- google apps (6)
- jboss (5)
- liferay (143)
- liferay 7.1 (11)
- liferay dxp (11)
- liferay7 (12)
- openshift (8)
- osgi (5)
- redhat (15)
- rest (6)
- wso2 (70)
- wso2 api-m (10)
- wso2 ei (8)
- wso2ei (5)
- wso2esb (7)
- wso2is (8)
- емдев (11)
Сайт использует файлы cookie. Они позволяют узнавать вас и получать информацию о вашем пользовательском опыте. Это нужно, чтобы улучшать сайт. Посещая страницы сайта и предоставляя свои данные, вы позволяете нам предоставлять их сторонним партнерам. Если вы согласны, продолжайте пользоваться сайтом. Если нет – установите специальные настройки в браузере или обратитесь в техподдержку.