, , ,

Соответсвие WSDL рекомендациям WS-I версии 1.1

понедельник, 26 января 2009 г. 0 коммент.

Обычная ситуация: делаешь сервисы, они хорошо работают.
Но тут приходит время использование сервисов внешними системами и оказывается, что сделанные сервисы не соответсвуют рекомендациям WS-I и хоть это и рекомендации, но внешние системы все эти рекомендации соблюдают, а твои сервисы нет. :(

Рассмотрим один случай. Есть WSDL.


<?xml version="1.0" encoding="UTF-8"?>
<definitions
name="test_wsdl"
targetNamespace="http://xmlns.oracle.com/test_wsdl"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:ns1="http://xmlns.oracle.com/test_scheme"
xmlns:client="http://xmlns.oracle.com/test_wsdl">
<!--> start cut
...
end cut </!-->
<types>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:import namespace="http://xmlns.oracle.com/test_scheme"
schemaLocation="test_scheme.xsd"/>
</xsd:schema>
<!--> start cut
...
end cut </!-->
</types>
<message name="test_wsdl_getdata1RequestMessage">
<part name="payload" element="ns1:Request"/>
</message>
<message name="test_wsdl_getdata1ResponseMessage">
<part name="payload" element="ns1:Response"/>
</message>
<message name="test_wsdl_getdata2RequestMessage">
<part name="payload" element="ns1:Request"/>
</message>
<message name="test_wsdl_getdata2ResponseMessage">
<part name="payload" element="ns1:Response"/>
</message>
<!--> start cut
...
end cut </!-->
<portType name="test_wsdl">
<operation name="getdata1">
<input message="tns:test_wsdl_getdata1RequestMessage"/>
<output message="tns:test_wsdl_getdata2ResponseMessage"/>
</operation>
<operation name="getdata2">
<input message="tns:test_wsdl_getdata2RequestMessage"/>
<output message="tns:test_wsdl_getdata2ResponseMessage"/>
</operation>
<!--> start cut
...
end cut </!-->
</portType>
<binding name="test_wsdlBinding" type="tns:test_wsdl">
<soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="getdata1">
<soap:operation style="document" soapAction="subscribe"/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
<operation name="getdata2">
<soap:operation style="document" soapAction="getdata"/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
<!--> start cut
...
end cut </!-->
</binding>
<service name="test_wsdl">
<port name="test_wsdlPort" binding="tns:test_wsdlBinding">
<soap:address
location="http://myhost:80/orabpel/domain_test/test_wsdl/1.0"/>
</port>
</service>
<plnk:partnerLinkType name="test_wsdl">
<plnk:role name="test_wsdlProvider">
<plnk:portType name="tns:test_wsdl"/>
</plnk:role>
</plnk:partnerLinkType>
</definitions>

Проверяем wsdl программкой взятой с родного сайта: Interoperability Testing Tools 1.1

Assertion: BP2120
Failure Detail Message
getdata1,
getdata2
Element Location: lineNumber=96

В логе видим, что пункт "BP2120" не выполнен. Ошибка вот в этой строке:

<binding name="test_wsdlBinding" type="tns:test_wsdl">

Читаем про это: Test Assertion: BP2120
Хм, в байдинге не уникальные операции. Читаем дальше требования:
R2710

4.7.6 Operation Signatures

Definition: operation signature

The profile defines the "operation signature" to be the fully qualified name of the child element of SOAP body of the SOAP input message described by an operation in a WSDL binding.

In the case of rpc-literal binding, the operation name is used as a wrapper for the part accessors. In the document-literal case, since a wrapper with the operation name is not present, the message signatures must be correctly designed so that they meet this requirement.

An endpoint that supports multiple operations must unambiguously identify the operation being invoked based on the input message that it receives. This is only possible if all the operations specified in the wsdl:binding associated with an endpoint have a unique operation signature.

R2710The operations in a wsdl:binding in a DESCRIPTION MUST result in operation signatures that are different from one another.


Оказывается все просто. Точка входа (вызова) должна быть однозначно определена, в нашем случае part и element одинаковые для операций getdata1 и getdata2.

<message name="test_wsdl_getdata1RequestMessage">
<part name="payload" element="ns1:Request"/>
</message>

<message name="test_wsdl_getdata2RequestMessage">
<part name="payload" element="ns1:Request"/>
</message>

Изменеяем схему, добавляем новый элемент Request2, копию Request1 и используем его.

<message name="test_wsdl_getdata1RequestMessage">
<part name="payload" element="ns1:Request"/>
</message>
<message name="test_wsdl_getdata2RequestMessage">
<part name="payload" element="ns1:Request2"/>
</message>
Читать полностью

, , ,

Как получить userName из WS-Security soap-заголовка

четверг, 22 января 2009 г. 0 коммент.

Иногда в BPEL-процессе необходимо знать, какой пользователь вызвал этот web-сервис. Хорошо, когда имя пользователя передается в структуре сообщения, но когда имя пользователя необходимо получить из заголовка soap-сообщенини, то возникают небольшие трудности. Дело осложняется, если сервис защищен, например OWSM, с авторизацией в каком-нибудь LDAP-каталоге. Посмотрим как их можно решить.

Посмотрим на рисунок.



В этом "PipeLine" выполняются шаги по извлечению информации для авторизации "Extract Credentials", аутентификации "Ldap Authenticate" и авторизации "Ldap Authorize".
После выполнения шага "Extract Credentials" из сообщения удаляется информация о пользователе и пароле, поэтому чтобы получить необходимую информацию, добавим шаг "XML Transform", где укажем свою xsl-трансформацию.


<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:ns1="http://xmlns.oracle.com/test_soap"
version="1.0" >
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="ns1:input">
<xsl:element name="{name()}">
<xsl:value-of select="/soap:Envelope/soap:Header/wsse:Security/wsse:UsernameToken/wsse:Username"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>

Трансформация копирует сообщение один в один за исключением одного элемента "ns1:input", в этом элемент мы копируем имя пользователя. Читать полностью