SOAP Header on WS-Security response - web-services

Is SOAP Header obligatory on WS-Security Response? If so, why?
I am wondering because my client complains about no SOAP Header in server's response (which in fact is missing), and there is no way to configure it.
I am using a bit obsolete technology (Axis2+Rampart 1.4).
This is security policy:
<wsp:Policy wsu:Id="SigOnly" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
<wsp:ExactlyOne>
<wsp:All>
<sp:AsymmetricBinding xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<wsp:Policy>
<sp:InitiatorToken>
<wsp:Policy>
<sp:X509Token sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/Once">
<wsp:Policy>
<sp:WssX509V3Token10/>
</wsp:Policy>
</sp:X509Token>
</wsp:Policy>
</sp:InitiatorToken>
<sp:RecipientToken>
<wsp:Policy>
<sp:X509Token sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/Once">
<wsp:Policy>
<sp:WssX509V3Token10/>
</wsp:Policy>
</sp:X509Token>
</wsp:Policy>
</sp:RecipientToken>
<sp:AlgorithmSuite>
<wsp:Policy>
<sp:TripleDesRsa15/>
</wsp:Policy>
</sp:AlgorithmSuite>
<sp:Layout>
<wsp:Policy>
<sp:Strict/>
</wsp:Policy>
</sp:Layout>
<sp:IncludeTimestamp/>
<sp:OnlySignEntireHeadersAndBody/>
</wsp:Policy>
</sp:AsymmetricBinding>
<sp:SignedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<sp:Body/>
</sp:SignedParts>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>

Response policy was applied. The problem lied in Rampart's code - it expected the header as defined in WS-Security 1.1, but the server was using WS-Security 1.0, where this header is not obligatory.
It required to shadow org.apache.rampart.util.RampartUtil class
with local one, with redefined isSecHeaderRequired so that it always returns False on incoming messages.
This complies with WS-Security 1.0 standard, which does not say a word wheter the header is required. WS-Security 1.1 requires the header implicitly when a Signature was used (https://docs.oasis-open.org/wss/v1.1/wss-v1.1-spec-os-SOAPMessageSecurity.pdf, chapter 8.5.1)

As Barbara already pointed out. The reason is that the policy applied on client side does not match the one on the server side.
E.g. the tag
<sp:IncludeTimestamp/>
in your policy causes the client to send out the request with a wsse tag in the SOAP header like this
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" soapenv:mustUnderstand="true">
....
<wsu:Timestamp wsu:Id="TS-F89FADB76552899AC314938177135681">
<wsu:Created>2017-05-03T13:21:53.566Z</wsu:Created>
<wsu:Expires>2017-05-03T13:26:53.566Z</wsu:Expires>
</wsu:Timestamp>
...
</wsse:UsernameToken>
</wsse:Security>
And by the policy the client expects to receive from the server a <wsu:Timestamp> tag underneath a <wsse> tag in the response so that it can check the timestamp policy on client side. If the server does not produce an answer that matches the policy (e.g. because the server is producing the response SOAP message using a different policy.) then the acceptance of the response fails.
In my case the server was responding with an empty SOAP header (without a <wsse> tag at all). This resulted in the following exception:
org.apache.axis2.AxisFault: Missing wsse:Security header in request
at org.apache.rampart.handler.RampartReceiver.setFaultCodeAndThrowAxisFault(RampartReceiver.java:186)
at org.apache.rampart.handler.RampartReceiver.invoke(RampartReceiver.java:99)
....
Changing the policy on client side to something the server was configured to return did the job.

This may seem obvious, but if you want a client with this policy applied to not throw an exception on the response, yes, the response must contain a Security header in the SOAP message and that header must contain a Timestamp and Signature.
I'm assuming that the request policy is applied on the server since you didn't get a MustUnderstand failure in the response. Are you sure that the response policy is also applied?

Related

WSO2 : RAMPARTUTIL throwing null pointer execption

I have created a web services with RAMPART implementation.
Flow of the Service :
Sender -> Sign Message Using His private key -> Encrypt Message using Server public Key -> sends to Receiver
Receiver -> authenticate message using sender's Public key -> decrypts Message using his private key -> processes the information.
Issue:
Client is Signing & Encrypting Message & sent to server
Server is authenticating & decypting the message successfully.
Now,
post decrypting the message the server processes the values
& has to respond back to client the status.
on return, I am getting following error:
SEVERE: Servlet.service() for servlet [AxisServlet] in context with path [/webService] threw exception
java.lang.NullPointerException
org.apache.rampart.util.RampartUtil.setKeyIdentifierType(RampartUtil.java:1389)
org.apache.rampart.builder.BindingBuilder.getSignatureBuilder(BindingBuilder.java:266)
org.apache.rampart.builder.BindingBuilder.getSignatureBuilder(BindingBuilder.java:250)
org.apache.rampart.builder.AsymmetricBindingBuilder.doSignature(AsymmetricBindingBuilder.java:760)
org.apache.rampart.builder.AsymmetricBindingBuilder.doSignBeforeEncrypt(AsymmetricBindingBuilder.java:417)
org.apache.rampart.builder.AsymmetricBindingBuilder.build(AsymmetricBindingBuilder.java:88)
org.apache.rampart.MessageBuilder.build(MessageBuilder.java:147)
org.apache.rampart.handler.RampartSender.invoke(RampartSender.java:65)
org.apache.axis2.engine.Phase.invokeHandler(Phase.java:340)
org.apache.axis2.engine.Phase.invoke(Phase.java:313)
org.apache.axis2.engine.AxisEngine.invoke(AxisEngine.java:262)
org.apache.axis2.engine.AxisEngine.sendFault(AxisEngine.java:516)
org.apache.axis2.transport.http.AxisServlet.handleFault(AxisServlet.java:433)
org.apache.axis2.transport.http.AxisServlet.doPost(AxisServlet.java:216)
javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:306)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:550)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:380)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:243)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:166)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:288)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Also, i have implemented the service without RAMPART, in that case the response is successful.
Please advice, I am struggling with from past 2 days..
not able to understand what m i missing since Request decryption is successful, but response is throwing exception.
i added the below block and the error was resolve:
<sp:Wss10 xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<wsp:Policy>
<sp:MustSupportRefKeyIdentifier/>
<sp:MustSupportRefIssuerSerial/>
</wsp:Policy>
</sp:Wss10>

How to call, invoke or test a Web Service that has Wssp Policy attached?

I'm unable to test a web service that has a Security Policy attached. I have been required to develop several Web Services and protect them with simple user and password. There is no further security requeriments (no encription, no SSL, etc).
In order to test the security bits, I built a dummy web service with top-down method using jDeveloper11G. The simple service works and can be tested vía HTTP analyzer and invoked with SoapUI while running in the integrated WebLogic server. The service also works when deployed to a stand alone WebLogic 10.3.6.0 server.
Then I try to attach security policies. I have succesfully attached using two methods:
1) At development time by adding the #Policy annotation
2) After deployment using the WLS console, going to the Web Service Configuration tab, then WS-Policy and attaching a policy and letting the console update the deployment plan as per instructed in this document.
(After any of these options the HTTP Analyzer is unable to test the service as it doesn't generate the SOAP stucture form to fill in the parameters, nor it allows to paste the text for a request. The Test applet in the server console can't access the WSDL either, so I'm left with SoapUI only)
I conclude that the attachment is correct because when consulting the WSDL from the server, it has Polici related nodes, where the original I wrote doesn't.
The problem comes when I test with SoapUI 5.0.0.
If I don't add any type of user/password information, the response contains:
<env:Fault>
<faultcode>env:Server</faultcode>
<faultstring>Unknown exception, internal system processing error.</faultstring>
</env:Fault>
If I add the following headers:
<soapenv:Header>
<wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken wsu:Id="UsernameToken-1" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:Username>usertext</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">passwordtext</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
then the response changes to:
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<env:Body>
<env:Fault xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<faultcode>wsse:InvalidSecurity</faultcode>
<faultstring>Error codes: 3001 4001 3201 1008 1028 Error code:3001</faultstring>
</env:Fault>
</env:Body>
</env:Envelope>
If I add the security information in the properties of the request without removing the headers I added manually to the request then the response becomes:
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<env:Body>
<env:Fault xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<faultcode>wsse:InvalidSecurity</faultcode>
<faultstring>Error on verifying message against security policy Error code:1025</faultstring>
</env:Fault>
</env:Body>
</env:Envelope>
The properties I change are: Username, Password, Domain, WSS-Password type (PasswordText), WSS-TimeToLive(50000). The property Authentication Type shows the fixed value "No Authorization" and cannot be changed.
If at this point I remove the manually added header the response becomes the same as the second response I included.
I have tried the following pre defined policies:
Wssp1.2-2007-Wss1.1-UsernameToken-Plain-X509-Basic256.xml
Wssp1.2-2007-Wss1.0-UsernameToken-Plain-X509-Basic256.xml
Wssp1.2-2007-Https-BasicAuth.xml
Wssp1.2-2007-Https-UsernameToken-Plain.xml
(The last two produce a different error related to the SSL configuration of the server)
I have also made several searches of wsse:InvalidSecurity, and the related error codes in the fault string, but have obtained no relevant information.
I have read several Oracle Docs (such like E17904_01, E23943_01, E12461_01), but there is no information on what to do after attaching the policies nor I find specific informaion on how to modify the request in order to fulfill the security requirements. Also made several searches for examples or the errors I get in this site and others.
So the question is What further steps are needed to be able to invoke this web service while protecting it with plain text user and password?
Secondary question is where do I specify which users can access the service? At the moment I assume that any user in the default realm will have access and so I'm testing with a user for wich I now the password in the default security realm "myrealm".
The wsdl as returned by the server after the policy is attached follows:
<!--
Published by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is Oracle JAX-WS 2.1.5.
-->
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="asegurado.institution.org" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wssutil="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" targetNamespace="asegurado.institution.org">
<wsp:UsingPolicy wssutil:Required="true" />
<wsp:Policy wssutil:Id="Wssp1.2-2007-Wss1.0-UsernameToken-Plain-X509-Basic256.xml">
<ns0:AsymmetricBinding xmlns:ns0="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
<wsp:Policy>
<ns0:InitiatorToken>
<wsp:Policy>
<ns0:X509Token ns0:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
<wsp:Policy>
<ns0:WssX509V3Token10/>
</wsp:Policy>
</ns0:X509Token>
</wsp:Policy>
</ns0:InitiatorToken>
<ns0:RecipientToken>
<wsp:Policy>
<ns0:X509Token ns0:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/Never">
<wsp:Policy>
<ns0:WssX509V3Token10/>
</wsp:Policy>
</ns0:X509Token>
</wsp:Policy>
</ns0:RecipientToken>
<ns0:AlgorithmSuite>
<wsp:Policy>
<ns0:Basic256/>
</wsp:Policy>
</ns0:AlgorithmSuite>
<ns0:Layout>
<wsp:Policy>
<ns0:Lax/>
</wsp:Policy>
</ns0:Layout>
<ns0:IncludeTimestamp/>
<ns0:ProtectTokens/>
<ns0:OnlySignEntireHeadersAndBody/>
</wsp:Policy>
</ns0:AsymmetricBinding>
<ns0:SignedEncryptedSupportingTokens xmlns:ns0="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
<wsp:Policy>
<ns0:UsernameToken ns0:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
<wsp:Policy>
<ns0:WssUsernameToken10/>
</wsp:Policy>
</ns0:UsernameToken>
</wsp:Policy>
</ns0:SignedEncryptedSupportingTokens>
<ns0:Wss10 xmlns:ns0="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
<wsp:Policy>
<ns0:MustSupportRefKeyIdentifier/>
<ns0:MustSupportRefIssuerSerial/>
</wsp:Policy>
</ns0:Wss10>
</wsp:Policy>
<types>
<xsd:schema>
<xsd:import namespace="asegurado.institution.org" schemaLocation="http://hn-apli-dev:7001/Asegurado/asegurado?xsd=1" />
</xsd:schema>
</types>
<message name="intentarRequest">
<part name="request" type="tns:intentarRequest" />
</message>
<message name="intentarResponse">
<part name="response" type="tns:intentarResponse" />
</message>
<portType name="asegurado">
<operation name="intentar">
<input message="tns:intentarRequest" />
<output message="tns:intentarResponse" />
</operation>
</portType>
<binding name="aseguradoBinding" type="tns:asegurado">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
<operation name="intentar">
<wsp:PolicyReference URI="#Wssp1.2-2007-Wss1.0-UsernameToken-Plain-X509-Basic256.xml" />
<soap:operation style="document" soapAction="asegurado.isntitution.org/intentar" />
<input>
<soap:body use="literal" parts="request" />
</input>
<output>
<soap:body use="literal" parts="response" />
</output>
</operation>
</binding>
<service name="ServicioAsegurado">
<port name="asegurado" binding="tns:aseguradoBinding" />
</service>
</definitions>

How to pass a file as SOAP request to Mule SOAP client to consume service

I have a flow which is exposing a webservice :-
<flow name="ServiceFlow" doc:name="ServiceFlow">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8082" path="mainData" doc:name="HTTP"/>
<cxf:jaxws-service serviceClass="com.test.services.schema.maindata.v1.MainData" doc:name="SOAP"/>
<component class="com.test.services.schema.maindata.v1.Impl.MainDataImpl" doc:name="JavaMain_ServiceImpl"/>
</flow>
This web service have a operation insertDataOperation which takes all the input from SOAP request and insert it in Database...
My SOAP request is as follow :-
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v1="http://services.test.com/schema/MainData/V1">
<soapenv:Header/>
<soapenv:Body>
<v1:insertDataRequest>
<v1:Id>311</v1:Id>
<v1:Name>ttttt</v1:Name>
<v1:Age>56</v1:Age>
<v1:Designation>eeeee</v1:Designation>
</v1:insertDataRequest>
</soapenv:Body>
</soapenv:Envelope>
Now I have another web service client flow which is consuming this webservice and the flow is :-
<flow name="ClientFlow" doc:name="ClientFlow">
<file:inbound-endpoint responseTimeout="10000" connector-ref="File_Global" doc:name="File" path="E:\backup\test">
<file:filename-regex-filter pattern="SoapRequestInsert.xml" caseSensitive="false"/>
</file:inbound-endpoint>
<file:file-to-string-transformer encoding="UTF-8" mimeType="text/xml" doc:name="File to String"/>
<cxf:jaxws-client doc:name="SOAP" serviceClass="com.test.services.schema.maindata.v1.MainData" operation="insertDataOperation" port="MainDataPort" />
<http:outbound-endpoint exchange-pattern="request-response" host="localhost" port="8082" path="mainData" doc:name="HTTP"/>
</flow>
Now here I am trying to consume the webservice by using a file inbound endpoint and passing the SOAP request in the file SoapRequestInsert.xml .. But the issue is that I don't get any error but the data is not inserted in database.. I checked the log .. where I found it enters the insert method of webservice implementation class but it doesn't get the input value ... Please help ... I have taken the reference from the following :- Consuming a JAX-WS in a Mule ESB flow
But It's not working .. what should I do to make it consume successfully and insert into DB ??? Pls help
Because the file you are posting contains the whole SOAP envelope you can HTTP POST it as is:
<flow name="ClientFlow" doc:name="ClientFlow">
<file:inbound-endpoint responseTimeout="10000" connector-ref="File_Global" doc:name="File" path="E:\backup\test">
<file:filename-regex-filter pattern="SoapRequestInsert.xml" caseSensitive="false"/>
</file:inbound-endpoint>
<http:outbound-endpoint exchange-pattern="request-response" host="localhost" port="8082" path="mainData" doc:name="HTTP"/>
</flow>
Note that you may need to add the SOAP action header, before the http:outbound-endpoint:
<set-property name="SOAPAction"
value="http://services.test.com/schema/MainData/V1/insertDataOperation" />
The final working solution is as David suggested the flow and by setting SOAPAction before outbound endpoint :-
<set-property name="SOAPAction"
value="http://services.test.com/schema/MainData/V1/insertDataOperation" />

WS-Security: #EndpointConfig not working

I want to build a simple example webservice that is protected by username and password.
As a starting point I used: https://docs.jboss.org/author/display/JBWS/WS-Security
The problem: every client even with wrong or missing credentials can invoke the web service methods. So the #EndpointConfig seems to have no effect.
But I don't know how to dig deeper because I couldn't get more detailed information about the web service config by debugging and the jboss admin console.
Webservice class:
#WebService(serviceName="MyWebService", portName="MyWebServicePort")
#EndpointConfig(configFile = "WEB-INF/jaxws-endpoint-config.xml", configName = "myconfig")
public class MyWebService{...}
jaxws-endpoint-config.xml:
<?xml version="1.0" encoding="UTF-8"?>
<jaxws-config xmlns="urn:jboss:jbossws-jaxws-config:4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:javaee="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="urn:jboss:jbossws-jaxws-config:4.0 schema/jbossws-jaxws-config_4_0.xsd">
<endpoint-config>
<config-name>myconfig</config-name>
<property>
<property-name>ws-security.username</property-name>
<property-value>myusername</property-value>
</property>
<property>
<property-name>ws-security.password</property-name>
<property-value>mypassword</property-value>
</property>
</endpoint-config>
</jaxws-config>
Any suggestion to get unauthorized clients denied?
You basically need to publish your policy in your WSDL.
You have to add under binding section of your WSDL.
<binding name="SecurityServicePortBinding" type="tns:ServiceIface">
<wsp:PolicyReference URI="#SecurityServiceSignThenEncryptPolicy"/>
...
</binding>
And add the policy definition itself in your WSDL like.
<wsp:Policy wsu:Id="SecurityServiceSignThenEncryptPolicy" xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<wsp:ExactlyOne>
<wsp:All>
<sp:AsymmetricBinding xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
....
</wsp:ExactlyOne>
</wsp:Policy>
When you hit your service URL (e.g. http://localhost:8080/yourservice?wsdl), you should be able to see the policy reference in the returned WSDL. Otherwise, no authentication/encryption happens.

Axis 2 and Rampart- why does service return wsse:Security header in request?

I'm connecting to a secure service.
I have a SOAP UI project configured to use a jks file to provide the certificate, along with appropriate security settings to allow me to get a valid response.
I've have used AXIS 2 and Rampart to create a SOAP request from a JAVA project.
Using TCPMon I've managed to grab the SOAP request.
When the request runs in the JAVA project, I just get the response:
org.apache.axis2.AxisFault: Missing wsse:Security header in request
but if I take the same request, captured in TCPMon and put it in a SOAP UI project, I get a response successfully.
Anyone got any ideas?
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
soapenv:mustUnderstand="1">
<wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
wsu:Id="Timestamp-1">
<wsu:Created>2012-06-01T15:09:12.520Z</wsu:Created>
<wsu:Expires>2012-06-01T15:14:12.520Z</wsu:Expires>
</wsu:Timestamp>
<wsse:BinarySecurityToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"
ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"
wsu:Id="CertId-ECDB0E....01">
MIID4DCCA0mgAwIBAgIBFjAN....</wsse:BinarySecurityToken>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
Id="Signature-2">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
<ds:Reference URI="#Id-15..93">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<ds:DigestValue>
3wgvhJ8SI2soC..IA=</ds:DigestValue>
</ds:Reference>
<ds:Reference URI="#Timestamp-1">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<ds:DigestValue>
VlzDT69YEl..qTlbj0=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>
ZCRypw/..=</ds:SignatureValue>
<ds:KeyInfo Id="KeyId-ECD..2">
<wsse:SecurityTokenReference xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
wsu:Id="STRId-ECDB0E6..6193">
<wsse:Reference URI="#CertId-ECDB0E..01"
ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" />
</wsse:SecurityTokenReference>
</ds:KeyInfo>
</ds:Signature>
</wsse:Security></soapenv:Header><soapenv:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="Id-15..3"><ns2:ProductSearchV2Request xmlns:ns2="http://product.webservice.sxc.com">
<ns2:Strength>900</ns2:Strength>
<ns2:MaximumResultSetInd>true</ns2:MaximumResultSetInd>
<ns2:MaximumResultSet>100</ns2:MaximumResultSet>
</ns2:ProductSearchV2Request>
This is the WS-POLICY document that I'm using:
<?xml version="1.0" encoding="UTF-8"?>
<!--
!
! Copyright 2006 The Apache Software Foundation.
!
! Licensed under the Apache License, Version 2.0 (the "License");
! you may not use this file except in compliance with the License.
! You may obtain a copy of the License at
!
! http://www.apache.org/licenses/LICENSE-2.0
!
! Unless required by applicable law or agreed to in writing, software
! distributed under the License is distributed on an "AS IS" BASIS,
! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
! See the License for the specific language governing permissions and
! limitations under the License.
!-->
<wsp:Policy wsu:Id="SigOnly"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
<wsp:ExactlyOne>
<wsp:All>
<sp:AsymmetricBinding xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<wsp:Policy>
<sp:InitiatorToken>
<wsp:Policy>
<sp:X509Token
sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">
<wsp:Policy>
<sp:RequireThumbprintReference/>
<sp:WssX509V3Token10/>
</wsp:Policy>
</sp:X509Token>
</wsp:Policy>
</sp:InitiatorToken>
<sp:RecipientToken>
<wsp:Policy>
<sp:X509Token
sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/Never">
<wsp:Policy>
<sp:RequireThumbprintReference/>
<sp:WssX509V3Token10/>
</wsp:Policy>
</sp:X509Token>
</wsp:Policy>
</sp:RecipientToken>
<sp:AlgorithmSuite>
<wsp:Policy>
<sp:TripleDesRsa15/>
</wsp:Policy>
</sp:AlgorithmSuite>
<sp:Layout>
<wsp:Policy>
<sp:Strict/>
</wsp:Policy>
</sp:Layout>
<sp:IncludeTimestamp/>
<sp:OnlySignEntireHeadersAndBody/>
</wsp:Policy>
</sp:AsymmetricBinding>
<sp:Wss10 xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<wsp:Policy>
<sp:MustSupportRefKeyIdentifier/>
<sp:MustSupportRefIssuerSerial/>
</wsp:Policy>
</sp:Wss10>
<sp:SignedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<sp:Body/>
</sp:SignedParts>
<ramp:RampartConfig xmlns:ramp="http://ws.apache.org/rampart/policy">
<ramp:user>ctr</ramp:user>
<ramp:encryptionUser>ctr</ramp:encryptionUser>
<ramp:passwordCallbackClass>com.gtnet.rampart.PWCBHandler
</ramp:passwordCallbackClass>
<ramp:signatureCrypto>
<ramp:crypto provider="org.apache.ws.security.components.crypto.Merlin">
<ramp:property name="org.apache.ws.security.crypto.merlin.keystore.type">JKS</ramp:property>
<ramp:property name="org.apache.ws.security.crypto.merlin.file">build\resources\qa.jks</ramp:property>
<ramp:property name="org.apache.ws.security.crypto.merlin.keystore.password">123123</ramp:property>
</ramp:crypto>
</ramp:signatureCrypto>
</ramp:RampartConfig>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
Thanks
Alan
It looks as if the error isn't with the outbound request, but with handling the response.
The response doesn't have a security header and when we're trying to unencrypt it, an exception occurs.
I need to somehow change my Rampart configuration to only do outbound security, not inbound
I'll report back :)
Ok the problem was that once Rampart is engaged, it expects the response to have the same security header.
The way I solved the problem was by removing the handler to the Inflow security in the Rampart.mar file.
I'm not sure if this is the best fix, but it worked for us.
To remove the inflow handler:
Unpack the rampart.mar file
Comment out the Inflow section
Zip up the META_INF folder. Then rename the .zip file to be .mar
Now when you use this as there are no handlers defined for inflow, it will just use the standard Axis2 response handler.
I guess if you had several projects using Rampart where some had the security header in the response and some didn't you would need a different approach.
Another approach is detailed here.
It's probably a better approach :
http://blog.rampartfaq.com/2009/11/how-to-generate-non-secure-response-to.html
Exception:
org.apache.axis2.AxisFault: Missing wsse:Security header in request
at
org.apache.rampart.handler.RampartReceiver.setFaultCodeAndThrowAxisFault(RampartReceiver.java:180)
at
org.apache.rampart.handler.RampartReceiver.invoke(RampartReceiver.java:99)
at org.apache.axis2.engine.Phase.invoke(Phase.java:318) at
org.apache.axis2.engine.AxisEngine.invoke(AxisEngine.java:251) at
org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:160) at
org.apache.axis2.description.OutInAxisOperationClient.handleResponse(OutInAxisOperation.java:364)
at
org.apache.axis2.description.OutInAxisOperationClient.send(OutInAxisOperation.java:417)
at
org.apache.axis2.description.OutInAxisOperationClient.executeImpl(OutInAxisOperation.java:229)
After navigating a lot, and reading the same pages several times, I finally got a solution that satisfied me.
From previous post I Quote: "Ok the problem was that once Rampart is engaged, it expects the response to have the same security header." (as the request)
This is absolutely true!
I feel that the best approach is found in the following link: http://xacmlinfo.org/2012/11/09/disabling-ws-security-for-in-or-out-messages-in-axis2/
However, in my case, I didn't want to make a new module, so I decided to emulate the module in my code. I tried to explain it in three steps.
(First) I used a default policy (take from the previous link), as a method in my code. (It's worked for Axis 1.6.2 and the compatible version of Rampart)
private String getPolicy()
{
return "xml for policy"
}
Important the method must return the following xml as String (better reading)
<wsp:Policy wsu:Id="emptryPolicy"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsp:ExactlyOne>
<wsp:All>
<sp:TransportBinding xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<wsp:Policy>
</wsp:Policy>
</sp:TransportBinding>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
(Second) I created a Policy (object) based on the previous method.
InputStream stream = new ByteArrayInputStream(getPolicy().getBytes());
Policy p = PolicyEngine.getPolicy(stream);
(Third) I used the properties of KEY_RAMPART_IN_POLICY and KEY_RAMPART_OUT_POLICY.
Stub._getServiceClient().getOptions().setProperty(RampartMessageData.KEY_RAMPART_OUT_POLICY, the security policy of the web service);
Stub._getServiceClient().getOptions().setProperty(RampartMessageData.KEY_RAMPART_IN_POLICY, p);
Important
The security policy of the web service, depends on the security that the web service uses... If your provider supplied the policy in the wsdl, you would not have to struggle with this... but in other cases, you just use the Rampart Policies. In the rampart site, are examples described very clear for each type of security policy. (UsernameToken Authentication, AsymmetricBinding, etc.)
This example fashions a request with security and response without security.
It Works for me!
In my case same problem but i got success response by changing the soap request version name space uri in the stub. i have change the name space uri from "http://www.w3.org/2003/05/soap-envelope" to "http://schemas.xmlsoap.org/soap/envelope/".