Web-приложение WSO2 - добавляем шину - Web-приложение WSO2 - добавляем шину
Blogs
Breadcrumbs
В прошлых постах серсии мы рассмотрели:
- Как реализовать простейшее веб-приложение с использованием WSO2 Application Server и WSO2 Data Services Server для доступа к данным;
- Как реализовать проверку прав доступа (с управлением пользователями в WSO2 Identity Server).
Теперь рассмотрим как реализовать проверку прав доступа на уровне доступа к данным. Для этого мы будем использовать интеграционную шину WSO2 ESB.
Для чего нужна интеграционная шина
По идее, сам сервер WSO2 DSS имеет возмоность авторизовать доступ к сервисам - зачем нам промежуточный слой? На самом деле в данном случае - это просто пример. Но, при разработке сложных корпортативных информационных систем является правилом хорошего тона избегать прямого взаимодействия между системами. Иначе возникает интеграционное спаггети.
Использование шины позволяет упорядочить и централизовать все взаимодействие между системами, реализовав его в единой системе - интеграционной шине. Это позволяет разделить потребителей сервисов от их реализации. В нашем случае подобное разделение позволит, например, в будующем заменить сервис работы с базой (для хранения информации о пациентах) на какую-нибудь внутреннюю медецинскую систему, да еще работающую по собственному протоколу. Все изменения по взаимодействию с системой будут реализованы на строне шины, со сторону потребителя информации (нашего веб-приложения) ничего не изменится.
Одно из основных назначений шины - это реализация Proxy Service - в нашем случае это будет сервис между веб-приложением и WSO2 DSS на котором будет реализована авторизация запросов.
Реализация Proxy Service-а
Для реализации будем использвать WSO2 ESB 4.9.0 - скачать можно с сайта WSO2. Установка шины описана в одном из предыдущих постов - она штатная.
Не забываем прописать Offset=3 в repository/conf/carbon.xml - таким образом сервер не будет конфликтовать с другими серверами WSO2 использующимися в примере. Соответсвенно панель администратора будет доступна по адресу: https://144.76.92.85:9446/carbon
Далее для создания простейшего Proxy Service:
- входим в админку (admin/admin)
- Main -> Manage -> Services -> Add -> Proxy Service
- Выбираем Pass Through Proxy
- Для создания сервиса нам надо знать исходный End-Point - для этого заходим в админку WSO2 DSS, идем в сервисы, кликаем на нашем сервисе и копируем URL end-point-а ( в нашем случае https://localhost:9445/services/WSO2HealthIT/) :
- В WSO2 ESB при создании сервиса указываем имя: WSO2HealthITProxy и его end-point
- Кликаем Create - простейший Proxy Service готов.
Изменения в Веб-Приложении
В нашем приложении мы захардкодили URL сервиса в двух местах:
- QueryPatientDetailServlet.java - переменная dataServiceEP
- RegisterPatientServlet.java - DSSServerURL
Заменим обе переменные на новый URL : http://localhost:8283/services/WSO2HealthITProxy (который теперь указывает на шину).
Деплоим приложение - проверяем что все продолжает работать. При этом в админке шины в информации о нашем proxy service-е мы можем увидеть, что работа идет именно через него (через статистику)
Интеграция XACML в Proxy Service
Как мы помним - штатным средством для описания прав доступа является протокол XACML - дальше мы научим шину управляеть доступом к сервису используя этот протокол.
Передача авторизационной информации из веб-приложения
Но для начала необходимо передать информацию о пользователе из приложения в шину. Для этого вносим изменения в классы QueryPatientDetailServlet и RegisterPatientServlet и инициализацию сервиса - добавляем информацию о пользователе в header-ы запроса
List<Header> headers = new ArrayList<Header>(); Header authHeader = new Header("X-Authorization", (String) request.getSession(false).getAttribute("user")); headers.add(authHeader); opt.setProperty(HTTPConstants.HTTP_HEADERS, headers);
В дальнейшем ESB получит эти данные из заголовка и будет знать, "кто" вызвал сервис.
Добавляем Entitlement медиатор в Proxy Service
Теперь вносим изменения в наш Proxy Service. Кликаем Edit на странице сервиса.
Можно использовать графический редактор, но на практике проще использовать XML-редактор (Switch to Source View в редакторе).
Для начала нам надо получить пользователя из заголовка:
<property name="username" expression="$trp:X-Authorization" scope="axis2" type="STRING"/>
Далее добавляем сам сервис
<entitlementService remoteServiceUrl="https://localhost:9444/services" remoteServiceUserName="admin" remoteServicePassword="enc:kuv2MubUUveMyv6GeHrXr9il59ajJIqUI4eoYHcgGKf/BBFOWn96NTjJQI+wYbWjKW6r79S7L7ZzgYeWx7DlGbff5X3pBN2Gh9yV0BHP1E93QtFqR7uTWi141Tr7V7ZwScwNqJbiNoV+vyLbsqKJE7T3nP8Ih9Y6omygbcLcHzg=" callbackClass="org.wso2.carbon.identity.entitlement.mediator.callback.UTEntitlementCallbackHandler" client="basicAuth"> <onReject> <log level="custom"> <property name="FAULT" value="ON REJECT CALLED"/> </log> <makefault version="soap11"> <code xmlns:soap11Env="http://schemas.xmlsoap.org/soap/envelope/" value="soap11Env:Server"/> <reason value="UNAUTHORIZED"/> <role/> <detail>XACML Authorization Failed</detail> </makefault> <property name="RESPONSE" value="true" scope="default" type="STRING"/> <header name="To" scope="default" action="remove"/> <send/> </onReject> <onAccept> <log level="custom"> <property name="FAULT" value="ON ACCEPT CALLED"/> </log> <send> <endpoint> <address uri="http://localhost:9765/services/WSO2HealthIT/"/> </endpoint> </send> </onAccept> <obligations/> <advice/> </entitlementService>
Итак - аналогично EntitlementFilter в веб-приложении мы обращаемся к WSO2 IS (https://localhost:9444/services) запрашивая информацию может ли указанный пользователь выполнять текущую операцию или нет.
Далее два блока:
- onReject - мы генерируем ошибку (makefault) которую потом обработаем в веб-приложении.
- onAccept - мы передаем управление в исходный сервис
В out-sequence нам надо убрать заголовки запроса (относящиеся к безопасности и просто отправить ответ):
<outSequence> <header xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" name="wsseSecurity" action="remove"/> <send/> </outSequence>
Добавляем правила доступа в WSO2 IS
Теперь надо добавить правиа доступа в WSO2 IS - аналогично тому, как мы это делали в свое время для веб-приложения
Логинимся в WSO2 IS (admin/admin) и далее Administration -> Add New Entitlement Policy -> write policy in XML
Берем dssOperationsProxy из исходников (https://github.com/akakunin/wso-health-tutorial/blob/3.0.x/is/dssOperationsPolicy.xml), сохраняем, далее "Publish to my PDP" и далее идем в Policy View и включаем Policy.
Не останавливаясь сейчас на формате XACML, в данном XML мы описали следующие правила:
Permissions user has | Access URL | Allow/ Deny |
---|---|---|
read | .*/WSO2HealthITProxy/patientDetailsByNumber | Allow |
read | .*/WSO2HealthITProxy/registerPatient | Deny |
write | .*/WSO2HealthITProxy/patientDetailsByNumber | Allow |
write | .*/WSO2HealthITProxy/registerPatient | Allow |
Добавляем обработку ошибок
Последним шагом будет обработка ошибок.
Обработка ошибок DSS
Наш Proxy Service "оборачивает" вызов к DSS. Если "что-то пойдет не так" то в сервисе будет вызван faultSequence. По этому, в наш сервис необходимо добавить
<target faultSequence="wso2HealthITFaultHandler">
(весь сервис можно посмотреть в исходниках: https://github.com/akakunin/wso-health-tutorial/blob/3.0.x/esb/WSO2HealthITProxy.xml)
Так же необходимо будет создать в ESB Sequence: Manage -> Sequences -> Add Sequence с именем wso2HealthITFaultHandler и кодом из репозитория: https://github.com/akakunin/wso-health-tutorial/blob/3.0.x/esb/wso2HealthITFaultHandler.xml)
Как итог - если с возникнет какая-либо ошибка ( на стороне DSS или например ошибка доступа) клиент в веб-приложении получит SoapFault Exception. Соотвественно везде где мы обращаемся к сервису нам необходимо добавить обработку Exception-а:
- В QueryPatientDetailServlet надо добавить следующий обработчик:
try { <doGet method> } catch (Exception e) { RequestDispatcher rd = getServletContext().getRequestDispatcher("/getPatientDetails.jsp"); PrintWriter out= response.getWriter(); out.println("<font color="red">Error While Querying Records : "+e.getMessage()+"</font>"); rd.include(request, response); }
- RegisterPatientServlet - просто поймать Exception
Итог
Как итог данного упражнения, мы добавили шину для связи между сервисами данных и веб-приложением, в которой реализовали проверку прав доступа и обработку ошибок.
Все исходники примера доступны в репозитории: https://github.com/akakunin/wso-health-tutorial/tree/3.0.x
- 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. Они позволяют узнавать вас и получать информацию о вашем пользовательском опыте. Это нужно, чтобы улучшать сайт. Посещая страницы сайта и предоставляя свои данные, вы позволяете нам предоставлять их сторонним партнерам. Если вы согласны, продолжайте пользоваться сайтом. Если нет – установите специальные настройки в браузере или обратитесь в техподдержку.