Custom Soap Header in asmx web serrvice - web-services

In an existing web service application(asmx services) I need to add new service which will be called through SOAP(java client), and it looks some thing like this
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:pus="http://www.example.org/pusheventservice/">
<soapenv:Header>
<pus:WSSecurity>
<Credentials>
<Username>someuser</Username>
<Password>somepwd</Password>
<Credentials>
</pus:WSSecurity>
<PUS:ServiceHeader>
<PUS:TransactionID>101</PUS:TransactionID>
<PUS:TransactionDate>2014/12/21</PUS:TransactionDate>
<PUS:TransactionTime>14:54</PUS:TransactionTime>
I Inherited class class ServiceHeader: SoapHeader having username,password, TransactionId... and mention [SoapHeader("userCredentials", Direction = SoapHeaderDirection.InOut)] with WebMethod.
but my resultant soap message is not be same as above.
What are the steps need to be done..

Related

Unable to invoke WSO2 API Manager 1.10 admin services

I have enabled the admin services from carbon.xml for API Manager and extracted the wsdl successfully. Now I am trying to invoke the service RemoteTenantManagerService using SOAP UI. I have loaded the wsdl in SOAP UI and also provided the Basic authentication Username/Password as admin/admin. But I am getting following message back. Port for API Manager is Offset 1
Request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://service.ws.um.carbon.wso2.org">
<soapenv:Header/>
<soapenv:Body>
<ser:getAllTenants/>
</soapenv:Body>
</soapenv:Envelope>
Response:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<soapenv:Fault>
<faultcode>soapenv:Server</faultcode>
<faultstring>The service cannot be found for the endpoint reference (EPR) /services/RemoteTenantManagerService.RemoteTenantManagerServiceHttpsSoap11Endpoint</faultstring>
<detail/>
</soapenv:Fault>
</soapenv:Body>
</soapenv:Envelope>
There are two types of transports, PassThrough and servlet. The admin services are exposed through servlet transport. Hence those must be invoked using servlet transport port.
For ex:- https://{host}:9443/services/RemoteTenantManagerService
In your case you have set offset to the "1" so please call the service using the URL https://{host}:9444/services/RemoteTenantManagerService
The generated WSDL contains the endpoint with Passthrough port hence soapUI shows it as the default endpoint. Please change the port to servlet port (your case it should be 9444) and run again.

SOAP requests run in SOAP UI but not in WSO2ESB "Try this service" page, so the related scheduled task doesn't work

I have deployed a custom Proxy Service in WSO2 ESB and I can't obtain any response from the web service i call with it in "Try this service" page. I've tried to send the request with SOAP UI passing through the Proxy Service of WSO2ESB (I put the endpoint of the Proxy Service, and NOT of the WS, in SOAP UI) and it works correctly. The same SOAP request doesn't work in the WSO2ESB page unreasonably.
So, when i create a scheduled task with the selected proxy service it returns me an error. I don't know how to change the content of the SOAP message in order to make it correct for ESB.
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http://ec.europa.eu/eurostat/sri/service/2.0">
<soapenv:Header/>
<soapenv:Body>
<ns:QueryStructure>
<!--Optional:-->
<ns:Query>
<RegistryInterface xsi:schemaLocation="http://www.SDMX.org/resources/SDMXML/schemas/v2_0/message SDMXMessage.xsd" xmlns="http://www.SDMX.org/resources/SDMXML/schemas/v2_0/message" xmlns:common="http://www.SDMX.org/resources/SDMXML/schemas/v2_0/common" xmlns:compact="http://www.SDMX.org/resources/SDMXML/schemas/v2_0/compact" xmlns:cross="http://www.SDMX.org/resources/SDMXML/schemas/v2_0/cross" xmlns:generic="http://www.SDMX.org/resources/SDMXML/schemas/v2_0/generic" xmlns:query="http://www.SDMX.org/resources/SDMXML/schemas/v2_0/query" xmlns:structure="http://www.SDMX.org/resources/SDMXML/schemas/v2_0/structure" xmlns:registry="http://www.SDMX.org/resources/SDMXML/schemas/v2_0/registry" xmlns:utility="http://www.SDMX.org/resources/SDMXML/schemas/v2_0/utility" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Header>
<ID>JD014</ID>
<Test>true</Test>
<Truncated>false</Truncated>
<Name xml:lang="en">Trans46302</Name>
<Prepared>2001-03-11T09:30:47-05:00</Prepared>
<Sender id="BIS"/>
</Header>
<QueryStructureRequest resolveReferences="false">
<registry:DataflowRef/>
</QueryStructureRequest>
</RegistryInterface>
</ns:Query>
</ns:QueryStructure>
</soapenv:Body>
</soapenv:Envelope>
This runs on SOAP UI (through ESB) and not on the same ESB.
For changing the content of a message you can use Payload Mediator.
There's also an example on how to do this.
Hope that helps.

How can I add WSSE Header to my Web Service Client?

I want to add wsse Security header to my web service client on ASP 3.5. I test the web service from SoapUI using this Soap Envelope and get an answer:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:comp="http://myCompany.org.tr"> <soapenv:Header xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"/>
<wsse:Username>MyUsername</wsse:Username>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
(Body Info.)
</soapenv:Body>
</soapenv:Envelope>
I want to create this envelope through classic Web Service Reference which created by Visual Studi 2012. Which class should I use to add Username Info to my envelope?
Thank you John, and Ladislav.
Turns out that you should add the header via web.config file to get properly ordered SOAP message. Otherwise .Net tries to nest your code with its own capsulation (even you dont ask for it), and sends some rubbish as a result.

Glassfish, EJB3, SOAP web service and basic authentication

I'm setting up a glassfish server with a single EJB3 as a mocked up backend for a POC. Everything was working fine until I went to add some basic authentication. Just plan text userid and password, nothing sophisticated for this job. I added the following annotations to the EJB:
#WebService(name = "Banking", serviceName = "Banking", targetNamespace = BANKING_NAMESPACE)
#DeclareRoles("user")
#Stateless
public class Banking {
...
#RolesAllowed("user")
#SOAPBinding(parameterStyle = ParameterStyle.BARE)
#WebMethod(action = BANKING_NAMESPACE + "/logon", operationName = "logon")
#WebResult(targetNamespace = XmlStrings.BANKING_MODEL_NAMESPACE)
public LogonResponse logon(#WebParam(targetNamespace = XmlStrings.BANKING_MODEL_NAMESPACE) Logon request) throws WebServiceException {
...
}
}
According to what I've read of EJB3 spec, this is pretty common for doing a SOAP web service.
However when I send this xml:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:mod="http://www.dhcbank.com/banking/model">
<soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken wsu:Id="UsernameToken-79" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:Username>fred</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">fred</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<mod:logon/>
</soapenv:Body>
</soapenv:Envelope>
I get the following error back as a SOAP fault:
java.lang.Exception: Client not authorized for invocation of public com.dhcbank.www.banking.schema.LogonResponse com.dhcbank.www.banking.Banking.logon(com.dhcbank.www.banking.schema.Logon) throws javax.xml.ws.WebServiceException
And in the glassfish log:
[#|2010-10-10T12:49:27.497+1100|INFO|glassfish3.0.1|javax.enterprise.system.core.security|_ThreadID=41;_ThreadName=http-thread-pool-8080-(2);|JACC Policy Provider: Failed Permission Check, context(BankingEAR/Banking_war_internal)- permission((javax.security.jacc.EJBMethodPermission Banking logon,ServiceEndpoint,com.dhcbank.www.banking.schema.Logon))|#]
In the glassfish admin screens I added a user called fred with a fred password and assigned it to a groups called user. But that didn't work.
I did some more reading which suggested that I create a sun-ejb-jar.xml file and add it to the ear file. So I created it with this content:
<sun-ejb-jar>
<enterprise-beans>
<ejb>
<ejb-name>Banking</ejb-name>
<webservice-endpoint>
<port-component-name>Banking</port-component-name>
<login-config>
<auth-method>BASIC</auth-method>
<realm>file</realm>
</login-config>
</webservice-endpoint>
</ejb>
</enterprise-beans>
</sun-ejb-jar>
This is as near as I can tell, correct. However I could not find anything that told me what the values of the port-component-name element should be. So I don't know if I've got it right.
Security does still not appear to be working and I cannot figure out why. Does anyone have any experience with this and can point me at what I've got wrong or not done?
I'm assuming your declared role "user" is the same role name in your file realm? if not provide this mapping in your descriptor:
<sun-ejb-jar>
<security-role-mapping>
<role-name>user</role-name>
<group-name>filerealm-group-name</group-name>
</security-role-mapping>
...
I don't think that you're currently creating the appropriate HTTP header for Basic Authentication. I'm not sure how you create the SOAP request but if you're using a JAX-WS client, the JAX-WS FAQ documents the following:
Q. How do I do basic authentication in JAX-WS?
You can do the following:
HelloService service = new HelloService();
Hello proxy = (service.getHelloPort());
((BindingProvider)proxy).getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "userfoo");
((BindingProvider)proxy).getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "passbar");
USERNAME_PROPERTY, PASSWORD_PROPERTY
are used primarily for service
requests. I think when you instantiate
Service, it fetches WSDL and the
server is returning 401. You could try
any one of the following solutions.
Use java.net.Authenticator class in your client application.
Provide a local access to the WSDL using catalog. There is a catalog
sample in the jax-ws distribution.
Configure web.xml to allow GET requests without authentication
And unless I'm wrong, the usernametoken would fit if the webservice expects the authentication in the SOAP header, which is not the case according to your description.
In other words, for me, you're currently not sending the credentials for the BASIC auth.
See also
Example: Basic Authentication with JAX-WS
SSL and HTTP BASIC authentication with Glassfish and JAX-WS (more complex scenario)

Move namespace declaration from payload to envelope on an axis created web service

I just created a web service client using axis and eclipse that does not work with my web service provider. The message created by the web service client looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<enviarMensajeRequest
xmlns="http://www.springframework.org/spring-ws/Imk-Zenkiu-Services">
<usuario>someuser</usuario>
<clave>somepassword</clave>
<mensaje>somemessage</mensaje>
<contacto>
<buzonSMS>somenumber</buzonSMS>
<primerNombre>somefirstname</primerNombre>
<primerApellido>somelastname</primerApellido>
</contacto>
</enviarMensajeRequest>
</soapenv:Body>
</soapenv:Envelope>
I see nothing wrong with the message but my provider insists the message should be:
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:imk="http://www.springframework.org/spring-ws/Imk-Zenkiu-Services">
<soapenv:Body>
<imk:enviarMensajeRequest>
<imk:usuario>someuser</imk:usuario>
<imk:clave>somepassword</imk:clave>
<imk:mensaje>somemessage</imk:mensaje>
<imk:contacto>
<imk:buzonSMS>somenumber</imk:buzonSMS>
<imk:primerNombre>somefirstname</imk:primerNombre>
<imk:primerApellido>somelastname</imk:primerApellido>
</imk:contacto>
</imk:enviarMensajeRequest>
</soapenv:Body>
</soapenv:Envelope>
Notice the namespace declaration moving from the enviarMensajeRequest to the soapenv:Envelope and the qualification with imk: on the parameters. I've tried many combinations on the process but my web service, wsdl and xml knowledge is very limited. The provider says that they can't help beyond telling me this. Any ideas? Perhaps a different framework that I can use to create the correct client.
Your provider is wrong, the messages are semantically equivalent; yours is unqualified, theirs is qualified. Are you using Axis or Axis2? If you're using Axis, I suggest you switch to Axis2 for a more robust, standards-compliant SOAP stack (both products are bad, but Axis2 is less-bad).
I assume you are creating your client with wsdl2java? If you can't get this tool to generate the message the way you like, then your best bet is to generate the message programmatically.
With Axis2, you can do this with the AXIOM API. See this link for some example API usage. Note that with most of the methods, e.g. createOMElement, you optionally pass the namespace prefix. So, if your provider requires it, then you could pass a String containing "imk" as the namespacePrefix parameter.
If you end up doing this programmatically and you are only going to be writing a simple client, then I STRONGLY suggest you abandon the Axis/Axis2 approach and use the JAX-WS stack instead, as it is part of Java since 1.6. The API is cleaner and the documentation is better. For example, following is a very simple client I wrote to send a SOAP request to our JIRA server. The sample code creates both qualified and unqualified elements.
QName port = new QName(endpoint, "subversionsoapservice-v2");
QName serviceName = new QName(endpoint, "ISubversionSoapServiceService");
Service service = Service.create(serviceName);
service.addPort(port, SOAPBinding.SOAP11HTTP_BINDING, endpoint);
Dispatch<SOAPMessage> dispatch = service.createDispatch(port, SOAPMessage.class, Service.Mode.MESSAGE);
MessageFactory factory = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL);
SOAPMessage request = factory.createMessage();
SOAPBody body = request.getSOAPBody();
SOAPElement reindexRepository = body.addChildElement("reindexRepository", "jira", "http://soap.ext.plugin.jira.atlassian.com");
SOAPElement in0 = reindexRepository.addChildElement("in0");
in0.addTextNode("test");
request.saveChanges();
dispatch.invoke(request);
The XML sent by the client looks like this:
<?xml version="1.0"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<jira:reindexRepository xmlns:jira="http://soap.ext.plugin.jira.atlassian.com">
<in0>test</in0>
</jira:reindexRepository>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>