How to add saml: XML prefix when creating LightSAML IDP response - laravel

When generating a response, LightSAML IDP samples show it generates Attributes as mapping rules in the URL format:
<AttributeStatement>
<Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress">
<AttributeValue>email#example.com</AttributeValue>
</Attribute>
</AttributeStatement>
Is there a way to tell LightSAML to generate Attributes as constructs in the generic format, like SimpleSAMLPHP does:
<saml:AttributeStatement>
<saml:Attribute Name="mail" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
<saml:AttributeValue xsi:type="xs:string">email#example.com</saml:AttributeValue>
</saml:Attribute>
</saml:AttributeStatement>
Apologies if I am using the incorrect terminology in my above question. Still learning SAML.

Related

How do you properly unmarshall an SOAP string with XML namespaces?

I'm having a hard time figuring out how to correctly and safely unmarshall a SOAP response with the following shape:
<xml>
<soap-env:Envelope
xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
<soap-env:Header></soap-env:Header>
<soap-env:Body>
<n0:ZcustomerMasterInfoResponse
xmlns:n0="urn:sap-com:document:sap:soap:functions:mc-style">
<EOutput>
...Additional tags
</EOutput>
<n0:ZcustomerMasterInfoResponse/>
</soap-env:Body />
</soap:Envelop />
</xml>
This would be trivial with basic tags but there's quite a few namespaces such as soap-env, n0 etc. that are making it more complex to parse.

Consuming XML response from a REST call in Spring Integration

Seems to be a simple task but I cannot get my head around it.
I have a Spring integration chain which calls an external Webservice, which returns an XML. I would like to use that XML response in a downstream XpathRouter.
What expected-response-type should I use?
<int:chain input-channel="filesChannel">
<!-- ... some previous components in the chain -->
<int-http:outbound-gateway
http-method="POST"
url="http://web/service/url"
expected-response-type="java.lang.String" />
<int-xml:xpath-router default-output-channel="resultChannel">
<int-xml:xpath-expression expression="/order/status" />
<int-xml:mapping value="Error" channel="importErrorChannel" />
</int-xml:xpath-router>
</int:chain>
It doesn't seem like the xpath-router can consume the XML returned by the webservice. When I debug the router with a breakpoint on the following line:
Node node = this.converter.convertToNode(message.getPayload());
The node is null, although the message does contain valid XML.
Is it because I am not setting the right expected-response-type?
Here is the response XML I receive from the service:
<apiResponse version="1.0">
<orders>
<order>
<orderReference>test_2_3045342</orderReference>
<status>Error</status>
<errors>
<error>
<errorCode>1100</errorCode>
<errorMessage><![CDATA[ "Field is required: dropWindow" ]]></errorMessage>
</error>
</errors>
</order>
</orders>
</apiResponse>
Ok, I found my mistake - it was actually in the XPATH expression. It should have been //order/status to enable deep search.
The java.lang.String expected-response-type works just fine with XML XpathRouter.
Thanks

Xpath not working in camel route

I'm sending soap xml through exchange object.When i try to route the request using xpath in apache camel,i'm not able to execute it properly.Please suggest
My Exchange body xml is
<Envelope><Header>
</Header>
<Body>
<Choice>
<Selector>1</selector>
</Choice>
</Body>
</Envelope>
My Camel Route
from(direct:XX)
.to(when(xpath("body()/Choice/Selector/.",String.class)=='1')
.to("direct:X")
.otherwise()
.to("direct:Y")
your Envelope cannot look like that. it must be something like:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
...
body()/Choice/Selector/. is not an Xpath. there is no such thing like body() in XPath.
Assuming that you have a SOAP Body content in the Exchange.body processed by some JAX-WS endpoint XPath will be
/Choice/Selector or /Choice/Selector/text() if it is an element with mixed content
BTW: if your Envelope is real example you try to test do not forget to fix your XML - you have wrong <Selector>1</selector> Tag names are case sensitive. It must be <Selector>1</Selector>

Soap Fault Details custom exception

In the process of moving to Spring WS and using JAXB from wsdl to generate the objects used in the Soap message. I am having an issue trying to get the Custom Exception into the details field of the Soap Fault message. The following is how the existing fault message is returned (FooException embedded in detail).
<env:Envelope xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<env:Header/>
<env:Body>
<env:Fault>
<faultcode>env:Server</faultcode>
<faultstring>Service specific exception: com.test.FooException: Invalid authentication credentials. Please try again.</faultstring>
<detail>
<n1:FooException xsi:type="n1:FooException" xmlns:n1="java:com.test">
<errorCode xsi:type="xsd:int">101</errorCode>
<errorReason xsi:type="xsd:string">InvalidUserCredentials:Invalid authentication credentials. Please try again</errorReason>
</n1:FooException>
</detail>
</env:Fault>
</env:Body>
</env:Envelope>
I have setup a customer exceptionResolver bean identifier in the spring config xml file.
<bean id="exceptionResolver" class="com.test.FacadeExceptionHandler">
<property name="order" value="1"></property>
<property name="defaultFault" value="SERVER"/>
<property name="exceptionMappings">
<value> com.test.FooException=SERVER,FaultMsg </value>
</property>
</bean>
I created the FacadeExceptionHandler and it is getting called, but I cannot figure out how to get the FooException into the details portion of the fault message.
Any help would be appreciated!!!
Thanks in advance for your help!
I think you almost get it all, in your FacadeExceptionHandler you must override the customizeFault method (doc) and then add the detail for the fault (you have your Exception as a parameter there).
All this custom detail handling for Soap Fault messages is explained in detail in this entry: http://www.stevideter.com/2009/02/18/of-exceptionresolvers-and-xmlbeans/
You cannot return to SOAP client fault with such depth of nested elements in <detail> element cause in Spring WS SoapFault has list of SoapFaultDetail which has list of SoapFaultDetailElement but SoapFaultDetailElement is just detail message in String. So in Spring WS max depth of SOAP Fault details is one.
<SOAP-ENV:Fault>
<faultcode>SOAP-ENV:Client</faultcode>
<faultstring>Сообщение не соответствуют схеме сервиса СМЭВ.</faultstring>
<detail>
<InvalidContent xmlns="urn://x-artefacts-smev-gov-ru/services/message-exchange/types/faults/1.1">cvc-complex-type.2.4.a: Invalid content was found starting with element 'ns:SenderProvidedRequestData1'. One of '{"urn://x-artefacts-smev-gov-ru/services/message-exchange/types/1.1":SenderProvidedRequestData}' is expected.</InvalidContent>
<InvalidContent xmlns="urn://x-artefacts-smev-gov-ru/services/message-exchange/types/faults/1.1">cvc-complex-type.2.3: Element 'ns:CallerInformationSystemSignature' cannot have character [children], because the type's content type is element-only.</InvalidContent>
<InvalidContent xmlns="urn://x-artefacts-smev-gov-ru/services/message-exchange/types/faults/1.1">cvc-complex-type.2.4.b: The content of element 'ns:CallerInformationSystemSignature' is not complete. One of '{WC["http://www.w3.org/2000/09/xmldsig#"]}' is expected.</InvalidContent>
</detail>
</SOAP-ENV:Fault>

Validate XML against 2 XSD

I'm trying to parse and validate a SOAP request with SAX. Two XSD are necessary, one for SOAP envelope (http://schemas.xmlsoap.org/soap/envelope/) and the one I defined. I cannot find a way to properly validate the request against these two XSD.
Here's the code I use to parse the request and validate it against soapenv.xsd. It works fine. If I specify my XSD instead, the validation fails with "Cannot find the declaration of element 'soapenv:Envelope'".
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setNamespaceAware(true);
factory.setValidating(true);
SAXParser saxParser = factory.newSAXParser();
saxParser.setProperty("http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema");
saxParser.setProperty("http://java.sun.com/xml/jaxp/properties/schemaSource", MyClass.class.getResourceAsStream("/xml/soapenv.xsd"));
InputSource is = new InputSource(MyClass.class.getResourceAsStream("/xml/request.xml"));
XMLReader reader = saxParser.getXMLReader();
reader.setContentHandler(new MyHandler());
reader.setErrorHandler(new MyErrorHandler());
reader.parse(is);
How can I specify a second XSD?
Is there a better way to parse and validate SOAP requests?
EDIT
As proposed, I created thirdpty.xsd that imports my two XSDs.
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="thirdparty:general"
xmlns="thirdparty:general"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:import schemaLocation="D:\ucfed\ValidateWSDL\src\xml\soapenv.xsd"
namespace="http://schemas.xmlsoap.org/soap/envelope/"/>
<xs:import schemaLocation="D:\ucfed\ValidateWSDL\src\xml\Presence.xsd"
namespace="thirdparty:presence"/>
</xs:schema>
I specify this new XSD for the validation:
saxParser.setProperty("http://java.sun.com/xml/jaxp/properties/schemaSource", MyClass.class.getResourceAsStream("/xml/thidpty.xsd"));
But still, only the SOAP envelope XSD is used for validation. If a modify one element from my other XSD, the validation does not detect it.
Here is the xml I am trying to validate
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="thirdparty:presence">
<soapenv:Header/>
<soapenv:Body>
<urn:getPresenceQuery>
<urn:origAccount uri="test#origin.com"/>
<urn:destAccount uri="test#destination.com"/>
</urn:getPresenceQuery>
</soapenv:Body>
</soapenv:Envelope>
Other ideas ?
Write a driver schema document which imports the other two; validate against the driver.

Resources