This is what my code is creating:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ws="http://example.com">
<soapenv:Header/>
<soapenv:Body>
<ws:isUserExists>
<userId>10</userId>
</ws:isUserExists>
</soapenv:Body>
</soapenv:Envelope>
In my soapenv:Envelope || xmlns:soapenv is coming twice
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
Now this is what I need:
here xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" is not present in the SOAP request
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/ " xmlns:ws="http://example.com">
<soapenv:Header/>
<soapenv:Body>
<ws:isUserExists>
<userId>10</userId>
</ws:isUserExists>
</soapenv:Body>
</soapenv:Envelope>
The java code which I am using to create the request is:
public static SOAPMessage createIsUserExistsSOAPRequest(User user) throws SOAPException
{
MessageFactory messageFactory =MessageFactory.newInstance();
SOAPMessage soapMessage = messageFactory.createMessage();
soapMessage.getSOAPHeader().setPrefix("soapenv");
SOAPPart soapPart = soapMessage.getSOAPPart();
// SOAP Envelope
SOAPEnvelope envelope = soapPart.getEnvelope();
envelope.setPrefix("soapenv");
envelope.addNamespaceDeclaration("ws","http://example.com");
// SOAP Body
SOAPBody soapBody = envelope.getBody();
soapBody.setPrefix("soapenv");
SOAPElement ensureUserExistsElem = soapBody.addChildElement("isUserExists", "ws");
SOAPElement userIdElem = ensureUserExistsElem.addChildElement("userId");
userIdElem.addTextNode(user.userId);
String authorization = new sun.misc.BASE64Encoder().encode(("someid#gmail.com").getBytes());
MimeHeaders hd = soapMessage.getMimeHeaders();
hd.addHeader("Authorization", "Basic " + authorization);
soapMessage.saveChanges();
return soapMessage;
}
Please help : what I am doing wrong?
In my soapenv:Envelope || xmlns:soapenv is coming twice
It does not appear twice. You're defining 2 prefixes that are bound to the same namespace.
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
Please help : what I am doing wrong?
Nothing. It does not matter if the namespace prefix is soapenv or SOAP-ENV or polar-bear-ninjas. As long as the prefix is bound to a namespace you are fully qualifying that XML element. Both XMLs are valid and it does not matter which prefix is used.
Related
I have a SOAP web service. When it is called, I return a response this way:
#PayloadRoot(namespace = NAMESPACE_URI, localPart = "...")
#ResponsePayload
public JAXBElement<MyResponseObject> mySoapService(#RequestPayload MyRequestObject request) {
MyResponseObject res = new MyResponseObject();
res.setField("my field content");
...
return createJaxbElementWithPrefix(res, MyResponseObject.class, "prefix");
}
Testing with SoapUI, the returned XML is
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<prefix:MyResponseObject xmlns:prefix="http://..url">
<field>my field content</field>
</prefix:MyResponseObject>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Unfortunately, for some reason that's beyond my control, the systems who calls my service, expects the prefix namespace in the envelope, so something like this:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:prefix="http://..url">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<prefix:MyResponseObject>
<field>my field content</field>
</prefix:MyResponseObject>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
This brings to my problem. I need to manually modify the Envelope, but I can't find a way. Could someone help me?
I am having trouble getting WCF binding to work with Blackboard Java Web Services API.
(Simple answer would be if anyone has got this working could you
please post a working binding for WCF to Blackboard)
I have spent hours trying different configurations and custom coded bindings.
Some unsuccessful attempts:
calling-a-ws-security-java-web-service-with-c-sharp-client
wcf-client-with-ws-security 12-common-wcf-interop-confusions
configure-wcf-for-ws-security-with-username-over-https
wcf-client-connecting-to-java-soap-web-service-using-ws-security
ClearUsernameBinding
There are many more to do with JAVA and WS-Security with WCF but I wont go on.
It seems that every time I get one thing working another breaks. Now I feel like I am going around in circles and just making myself even more confused.
As my first test what I am trying to do is simple Initialize the Context object and Login using an Admin test user account with a WCF proxy.
Blackboard Doc ContextWS
To make sure that all of this worked I first I downloaded the sample code for .Net WSE 2.0 and tested that, it worked perfectly.
Now when I use WCF and binding I cannot get this same behaviour.
First the Successful exchange with very old WSE 2.0
===================================
WSE 2.0 ContextWS Initialization
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing" 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">
<soap:Header>
<wsa:Action>initialize</wsa:Action>
<wsa:MessageID>uuid:b975e989-a4ce-4e1e-abd6-500945346c40</wsa:MessageID>
<wsa:ReplyTo>
<wsa:Address>http://schemas.xmlsoap.org/ws/2004/03/addressing/role/anonymous</wsa:Address>
</wsa:ReplyTo>
<wsa:To>https://Blackboard.Server.Name/webapps/ws/services/Context.WS</wsa:To>
<wsse:Security soap:mustUnderstand="1">
<wsu:Timestamp wsu:Id="Timestamp-47d0d017-4fd1-46c2-b1b4-2431402cf847">
<wsu:Created>2015-07-16T04:58:02Z</wsu:Created>
<wsu:Expires>2015-07-16T05:03:02Z</wsu:Expires>
</wsu:Timestamp>
<wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="SecurityToken-1b71e23a-2d84-40a5-9509-b75902ec8b76">
<wsse:Username>session</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">nosession</wsse:Password>
<wsse:Nonce>lAW2qXrXZ1maNNkCEzlHGA==</wsse:Nonce>
<wsu:Created>2015-07-16T04:58:02Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
</soap:Header>
<soap:Body />
</soap:Envelope>
WSE 2.0 ContextWS Initialization Success Response
<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<ns:initializeResponse xmlns:ns="http://context.ws.blackboard">
<ns:return>c2762f357bbc42a4a88d33e4e42486b8</ns:return>
</ns:initializeResponse>
</soapenv:Body>
</soapenv:Envelope>
WSE 2.0 ContextWS Login Request
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing" 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">
<soap:Header>
<wsa:Action>login</wsa:Action>
<wsa:MessageID>uuid:a823128b-efb4-49e1-87d9-fd35167f0bfc</wsa:MessageID>
<wsa:ReplyTo>
<wsa:Address>http://schemas.xmlsoap.org/ws/2004/03/addressing/role/anonymous</wsa:Address>
</wsa:ReplyTo>
<wsa:To>https://Blackboard.Server.Name/webapps/ws/services/Context.WS</wsa:To>
<wsse:Security soap:mustUnderstand="1">
<wsu:Timestamp wsu:Id="Timestamp-c38daf19-6b39-4391-a3f8-bcc030064a3e">
<wsu:Created>2015-07-16T04:58:15Z</wsu:Created>
<wsu:Expires>2015-07-16T05:03:15Z</wsu:Expires>
</wsu:Timestamp>
<wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="SecurityToken-65948746-e616-436a-85f4-d2e1023e39be">
<wsse:Username>session</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">c2762f357bbc42a4a88d33e4e42486b8</wsse:Password>
<wsse:Nonce>T0xs8aiaiODMK3sfKgDQtg==</wsse:Nonce>
<wsu:Created>2015-07-16T04:58:15Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
</soap:Header>
<soap:Body>
<login xmlns="http://context.ws.blackboard">
<userid>test_admin</userid>
<password>TestPassword</password>
<clientVendorId>TestClient</clientVendorId>
<clientProgramId>TestPOC</clientProgramId>
<loginExtraInfo xsi:nil="true" />
<expectedLifeSeconds>10000000</expectedLifeSeconds>
</login>
</soap:Body>
</soap:Envelope>
WSE 2.0 ContextWS Login Success Response
<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<ns:loginResponse xmlns:ns="http://context.ws.blackboard">
<ns:return>true</ns:return>
</ns:loginResponse>
</soapenv:Body>
</soapenv:Envelope>
===================================
So I know that this works to our environment and I know the user can login.
Using WCF I am able to get the Initialization working but then it looses the session. It does not put the Returned Session ID into the Password field for the next message. I have tried to do this manually of course; but I get an error stating the Password field is read only.
Now for my WCF Configuration and code that has gotten me closest to the above communication.
WCF App.Config Binding
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
</system.serviceModel>
<bindings>
<customBinding>
<binding name="WCFSoapInteropJavaWS" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" >
<textMessageEncoding messageVersion="Soap11" writeEncoding="utf-8" />
<security authenticationMode="UserNameOverTransport" enableUnsecuredResponse="true" allowSerializedSigningTokenOnReply="true"
messageSecurityVersion="WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10"
includeTimestamp="true" allowInsecureTransport="true" canRenewSecurityContextToken="false" >
</security>
<httpsTransport authenticationScheme="Anonymous" />
</binding>
</customBinding>
</bindings>
<client>
<endpoint
address="https://Blackboard.Server.Name:443/webapps/ws/services/Context.WS"
binding="customBinding" bindingConfiguration="WCFSoapInteropJavaWS"
contract="ContextWS.ContextWSPortType" name="Context.WCFSoapInteropJavaWS" />
</client>
</system.serviceModel>
</configuration>
WCF C# code
public bool testWrapper(String userId, String userPassword){
try
{
context = new ContextWrapper("Context.WCFSoapInteropJavaWS");
context.ClientCredentials.UserName.UserName = "session";
context.ClientCredentials.UserName.Password = "nosession";
context.initialize();
//context.ClientCredentials.UserName.Password = "886d935527944f94a3526288e39a555e"; // SessionGUID_HERE Throws a Read Only Error for Pasword
bool retval = context.login(userId, userPassword, vendorId, programId, null, expectedLife);
return retval;
}
catch (System.Exception e)
{
lastError = e;
return false;
}
}
This is what the SOAP communication looks like.
WCF ContextWS Initialization Request
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
<VsDebuggerCausalityData xmlns="http://schemas.microsoft.com/vstudio/diagnostics/servicemodelsink">uIDPo+FmveflwUtMgSATRu3Ht9EAAAAAmYVJsX+bhUeYcTDsFqFktkqe8xmMiA1MpXouaouXgJwACQAA</VsDebuggerCausalityData>
<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<u:Timestamp u:Id="_0">
<u:Created>2015-07-16T07:15:05.109Z</u:Created>
<u:Expires>2015-07-16T07:20:05.109Z</u:Expires>
</u:Timestamp>
<o:UsernameToken u:Id="uuid-1237f56c-7c68-4d40-a756-7ff2c19a3235-1">
<o:Username>session</o:Username>
<o:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">nosession</o:Password>
</o:UsernameToken>
</o:Security>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"/>
</s:Envelope>
WCF ContextWS Initialization Success Response
<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<ns:initializeResponse xmlns:ns="http://context.ws.blackboard">
<ns:return>886d935527944f94a3526288e39a555e</ns:return>
</ns:initializeResponse>
</soapenv:Body>
</soapenv:Envelope>
WCF ContextWS Login Request
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
<VsDebuggerCausalityData xmlns="http://schemas.microsoft.com/vstudio/diagnostics/servicemodelsink">uIDPo+JmveflwUtMgSATRu3Ht9EAAAAAmYVJsX+bhUeYcTDsFqFktkqe8xmMiA1MpXouaouXgJwACQAA</VsDebuggerCausalityData>
<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<u:Timestamp u:Id="_0">
<u:Created>2015-07-16T07:15:14.033Z</u:Created>
<u:Expires>2015-07-16T07:20:14.033Z</u:Expires>
</u:Timestamp>
<o:UsernameToken u:Id="uuid-1237f56c-7c68-4d40-a756-7ff2c19a3235-1">
<o:Username>session</o:Username>
<o:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">nosession</o:Password>
</o:UsernameToken>
</o:Security>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<login xmlns="http://context.ws.blackboard">
<userid>Test_admin</userid>
<password>TestPassword</password>
<clientVendorId>TestClient</clientVendorId>
<clientProgramId>TestPOC</clientProgramId>
<loginExtraInfo xsi:nil="true"/>
<expectedLifeSeconds>10000000</expectedLifeSeconds>
</login>
</s:Body>
</s:Envelope>
WCF ContextWS Login Failed Response
<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<soapenv:Fault>
<faultcode>soapenv:Server</faultcode>
<faultstring>[WSFW001]Invalid session</faultstring>
<detail />
</soapenv:Fault>
</soapenv:Body>
</soapenv:Envelope>
As you can see the session return id has not been added to the password field on the login request so there is a "Invalid Session:
It all seemed to be going so well.
In short if anyone knows how to achieve a binding from a WCF Client to the Blackboard Java Webservice API and example would be fantastic. Other wise I am hoping that someone else that knows more about WCF Bindings to Java than I do might be able to take a look at the above see where I am going wrong.
Any help anyone can give me to get this working would be much appreciated so thanks. I really am hoping it is just something silly that I am missing.
Sorry for such a long detailed question.
Thanks to heaps of reading and some useful samples I was able to get this working. Blackboard with WCF.
Thanks go to both:
Ajadex Lopez
http://www.isyourcode.com/2010/08/attaching-oasis-username-tokens-headers.html
Johnny Lockhart
"Incoming message does not contain required Security header"
BB is buggie so you might do best to search the forum for WCF to find the post
Sample class
using System;
using System.ServiceModel.Description;
using System.ServiceModel.Channels;
using System.ServiceModel.Dispatcher;
using System.ServiceModel;
using System.Xml;
using System.Security.Cryptography;
using System.Text;
namespace BBWcfWrapper
{
/// <summary>
/// Coupled with the additional classes below, allows for injecting the WS-Security header into a WCF Service call without requiring SSL on the server.
/// </summary>
/// <remarks>http://isyourcode.blogspot.com/2010/08/attaching-oasis-username-tokens-headers.html</remarks>
public class BBWSSecurityBehavior : IEndpointBehavior
{
public MessageInspector MessageInspector { get; set; }
public BBWSSecurityBehavior(MessageInspector messageInspector)
{
MessageInspector = messageInspector;
}
public void Validate(ServiceEndpoint endpoint)
{ }
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{ }
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
if (this.MessageInspector == null) throw new InvalidOperationException("Caller must supply ClientInspector.");
clientRuntime.MessageInspectors.Add(MessageInspector);
}
}
public class MessageInspector : IClientMessageInspector
{
public MessageHeader[] Headers { get; set; }
public MessageInspector(params MessageHeader[] headers)
{
Headers = headers;
}
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
if (Headers != null)
{
for (int i = Headers.Length - 1; i >= 0; i--)
{
request.Headers.Insert(0, Headers[i]);
}
}
return request;
}
public void AfterReceiveReply(ref Message reply, object correlationState)
{
}
}
public class SecurityHeader : MessageHeader
{
public string SystemUser { get; set; }
public string SystemPassword { get; set; }
public SecurityHeader(string systemUser, string systemPassword)
{
SystemUser = systemUser;
SystemPassword = systemPassword;
}
public override string Name
{
get { return "Security"; }
}
public override string Namespace
{
get { return "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"; }
}
protected override void OnWriteStartHeader(XmlDictionaryWriter writer, MessageVersion messageVersion)
{
writer.WriteStartElement("wsse", Name, Namespace);
writer.WriteXmlnsAttribute("wsse", Namespace);
writer.WriteAttributeString("soap", "mustUnderstand", Namespace, "1");
}
protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
{
WriteHeader(writer);
}
private void WriteHeader(XmlDictionaryWriter writer)
{
var createDate = DateTime.Now;
//Start Parent Elements
writer.WriteStartElement("wsu","Timestamp","http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
writer.WriteAttributeString("wsu","id","http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd","Timestamp-6557466");
#region Start Child Elements
writer.WriteStartElement("wsu", "Created", XmlConvert.ToString(createDate, "yyyy-MM-ddTHH:mm:sszzzzzz"));
writer.WriteEndElement(); //End Created
writer.WriteStartElement("wsu", "Expires", XmlConvert.ToString(createDate.AddDays(1), "yyyy-MM-ddTHH:mm:sszzzzzz"));
writer.WriteEndElement(); //End Expires
#endregion
writer.WriteEndElement(); //End Timestamp
//Start Parent Elements
writer.WriteStartElement("wsse", "UsernameToken", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
writer.WriteXmlnsAttribute("wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
#region Start Child Elements
writer.WriteStartElement("wsse", "Username", null);
writer.WriteString(SystemUser);
writer.WriteEndElement();//End Username
writer.WriteStartElement("wsse", "Password", null);
writer.WriteAttributeString("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");
writer.WriteString(SystemPassword);
writer.WriteEndElement();//End Password
// unique Nonce value - encode with SHA-1 for 'randomness'
// in theory the nonce could just be the GUID by itself
// This is used to stop Replay attacks
writer.WriteStartElement("wsse", "Nonce", null);
writer.WriteString(GetSHA1String(Guid.NewGuid().ToString()));
writer.WriteEndElement();//Nonce
writer.WriteStartElement("wsu", "Created", null);
writer.WriteString(XmlConvert.ToString(createDate, "yyyy-MM-ddTHH:mm:sszzzzzz"));
writer.WriteEndElement(); //End Created
#endregion
writer.WriteEndElement();//End UsernameToken
writer.Flush();
}
protected string GetSHA1String(string phrase)
{
SHA1CryptoServiceProvider sha1Hasher = new SHA1CryptoServiceProvider();
byte[] hashedDataBytes = sha1Hasher.ComputeHash(Encoding.UTF8.GetBytes(phrase));
return Convert.ToBase64String(hashedDataBytes);
}
}
}
Example Use
calendar = new CalendarWrapper("Calendar.BB_WSSecurity_Binding");
//This adds a custom security Headder for WCF and Java WS-Security Interop
calendar.Endpoint.Behaviors.Add(new BBWSSecurityBehavior(new MessageInspector(BbWsAuth.SecurityHeader)));
calendar.initializeCalendarWS(false);
Simple Wrapper class
public class CalendarWrapper : CalendarWSPortTypeClient
{
public CalendarWrapper() : base() { }
public CalendarWrapper(string endpointConfigurationName) : base(endpointConfigurationName) { }
public CalendarWrapper(Binding binding, EndpointAddress remoteAddress) : base(binding, remoteAddress) { }
}
Config
<bindings>
<basicHttpsBinding>
<binding name="BB_WSSecurity_Binding" messageEncoding="Text" textEncoding="utf-8" maxReceivedMessageSize="4000000" >
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
</binding>
</basicHttpsBinding>
</bindings>
<client>
<endpoint address="https://xxxxxxxxxx/webapps/ws/services/Calendar.WS"
binding="basicHttpsBinding" bindingConfiguration="BB_WSSecurity_Binding"
contract="CalendarWS.CalendarWSPortType" name="Calendar.BB_WSSecurity_Binding" />
i want to add the name space for all the items in the SOAPbody, the configuration related to the XML manipulation is in below i added the name space for the header but it doesn't come to the SOAP-body
Boolean outboundProperty = (Boolean) smc.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if (outboundProperty.booleanValue()) {
SOAPMessage message = smc.getMessage();
try {
SOAPEnvelope envelope = smc.getMessage().getSOAPPart().getEnvelope();
System.out.println("Envelop : "+envelope);
envelope.addNamespaceDeclaration("sch", "http://api.jasperwireless.com/ws/schema");
SOAPHeader header = envelope.addHeader();
SOAPElement security =
header.addChildElement("Security", "wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
SOAPElement usernameToken =
security.addChildElement("UsernameToken", "wsse");
usernameToken.addAttribute(new QName("xmlns:wsu"), "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
SOAPElement username =
usernameToken.addChildElement("Username", "wsse");
username.addTextNode("XXXXXXXXX");
SOAPElement password =
usernameToken.addChildElement("Password", "wsse");
password.setAttribute("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");
password.addTextNode("XXXXXXXXXXXXXX");
//Print out the outbound SOAP message to System.out
message.writeTo(System.out);
System.out.println("");
} catch (Exception e) {
e.printStackTrace();
}
and below is the XML that is created from the above code
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sch="http://api.jasperwireless.com/ws/schema">
<S:Header>
<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>XXXXXX</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">XXXXXXX</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</S:Header>
<S:Body>
<GetTerminalsByMsisdnRequest xmlns="http://api.jasperwireless.com/ws/schema">
<messageId>my message</messageId>
<version>1.3</version>
<licenseKey>537bba2a-9406-4703-a900-a8fee7a3f310</licenseKey>
<msisdns>
<msisdn>65144099016324</msisdn>
</msisdns>
</GetTerminalsByMsisdnRequest>
</S:Body>
</S:Envelope>
but i wanted to generate it like the below sample. im completely new to java and SOAP please help me
<S:Body>
<sch:GetTerminalsByMsisdnRequest xmlns="http://api.jasperwireless.com/ws/schema">
<sch:messageId>my message</messageId>
<sch:version>1.3</version>
<sch:licenseKey>537bba2a-9406-4703-a900-a8fee7a3f310</licenseKey>
<sch:msisdns>
<sch:msisdn>65144099016324</msisdn>
</sch:msisdns>
</sch:GetTerminalsByMsisdnRequest>
</S:Body>
We are creating a webservice that came from a WSDL which the soap messagehas both a header and body in the request and response. How can you set this up to work with a Spring WS? I can not find any examples????
In WSDL
<wsdl11:message name="createCourseSectionRequest">
<wsdl11:part name="Parameters" element="tns:createCourseSectionRequest"/>
<wsdl11:part name="HeaderInfoParameters" element="tns:imsx_syncRequestHeaderInfo"/>
</wsdl11:message>
<wsdl11:message name="createCourseSectionResponse">
<wsdl11:part name="Response" element="tns:createCourseSectionResponse"/>
<wsdl11:part name="HeaderInfoResponse" element="tns:imsx_syncResponseHeaderInfo"/>
</wsdl11:message>
Endpoint
#PayloadRoot(localPart="CreateCourseSectionRequest", namespace="")
#ResponsePayload
public CreateCourseSectionResponse createCourseSection(CreateCourseSectionRequest req) {
//TODO
return null;
}
Example
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ims="http://www.imsglobal.org/services/lis/cmsv1p0/wsdl11/sync/imscms_v1p0">
<soapenv:Header>
<ims:imsx_syncRequestHeaderInfo>
<ims:imsx_version>?</ims:imsx_version>
<ims:imsx_messageIdentifier>?</ims:imsx_messageIdentifier>
<!--Optional:-->
<ims:imsx_sendingAgentIdentifier>?</ims:imsx_sendingAgentIdentifier>
</ims:imsx_syncRequestHeaderInfo>
</soapenv:Header>
<soapenv:Body>
.....
</soapenv:Body>
</soapenv:Envelope>
Here is the solution I came up with. It works, but I wish the header part of the Soap message was strongly typed. .NET takes care of this for you while in Java it looks like you have to do more work to replicate a strongly typed object for the header. At least I can access the request/response header of the envelope with MessageContext.
#PayloadRoot(localPart="readCourseSectionRequest", namespace="http://www.imsglobal.org/services/lis/cmsv1p0/wsdl11/sync/imscms_v1p0")
#ResponsePayload
public ReadCourseSectionResponse readCourseSection(#RequestPayload ReadCourseSectionRequest parameters, MessageContext messageContext) {
//SaajSoapMessage response = (SaajSoapMessage) messageContext.getResponse();
//SoapHeader header = response.getSoapHeader();
//header.addHeaderElement(new QName("http://www.w3.org/2005/08/addressing", "MessageID", parameters.getSourcedId()));
return new ReadCourseSectionResponse();
}
I am trying to create children nodes inside and it should look like the following
<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-21" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:Username>USER</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">PAASS</wsse:Password>
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">==</wsse:Nonce>
<wsu:Created>2012-02-22T16:27:29.088Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
with the following
SOAPEnvelope envelope = soapPart.getEnvelope();
SOAPElement userNameToken = envelope.getHeader().addChildElement("Usernametoken", WSSE_NS_PREFIX, WSSE_NS);
SOAPElement user = userNameToken.addChildElement("UserName", WSSE_NS, WSSE_NS_PREFIX);
i get the following error when attemping to do so:
NAMESPACE_ERR: An attempt is made to create or change an object in a way which is incorrect with regard to namespaces.
It seems that you mixed order of arguments (WSSE_NS vs WSSE_NS_PREFIX)
It should be
SOAPEnvelope envelope = soapPart.getEnvelope();
SOAPElement userNameToken = envelope.getHeader().addChildElement("Usernametoken", WSSE_NS_PREFIX, WSSE_NS);
SOAPElement user = userNameToken.addChildElement("UserName", WSSE_NS_PREFIX, WSSE_NS);