MPaul
MPaul

Reputation: 2733

Add cookie to HTTP header for SOAP call in ColdFusion

I basically want to add the ASP.NET_SessionId cookie to my HTTP request header when calling a SOAP web service through ColdFusion.

The web service is registered in the OnApplicationStart function of the Application.cfc component in ColdFusion.

<cfscript>
    objSoapHeader = XmlParse("<wsse:Security mustUnderstand=""true"" xmlns:wsse=""http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd""><wsse:UsernameToken><wsse:Username>MY_USERNAME</wsse:Username><wsse:Password>MY_PASSWORD</wsse:Password></wsse:UsernameToken></wsse:Security>");
    Application.UserWebService = CreateObject("webservice","MY_URL/UserService.asmx?WSDL");
    addSOAPRequestHeader(Application.UserWebService,"","",objSoapHeader,true);
</cfscript>

My web service is called as such:

<cfset Result = "#Application.UserWebService.SomeFunction("1", "DATA")#">

In order for the .Net server (where the web services are located) to remember my session state, I must pass the ASP.NET_SessionId cookie in the HTTP request header, but have no idea if this is even possible in ColdFusion.

I've researched for several hours but nothing has come of it as of yet, so has anyone successfully managed to pull this off?

Upvotes: 1

Views: 1452

Answers (2)

Leigh
Leigh

Reputation: 28873

Short Answer:

For CF9 / Axis1 try enabling sessions on the web service object.

ws = createObject("webservice", "http://localhost/MyWebService.asmx?wsdl");
ws.setMaintainSession( true );

For CF10+ / Axis2, see longer answer below:


(Disclaimer: Using cfhttp might be simpler, but I was curious and did some digging ..)

From what I have read, since CF10+ uses Axis2 for web services it should be possible to use the underlying methods to maintain session state through HTTP cookies.

Using the the links above, I put together a quick POC using a basic web service and was able to extract the cookie header from the web service client response:

// make initial request
ws = createObject("webservice", "http://localhost/MyWebService.asmx?wsdl");
ws.firstMethod();

// For maintainability, use constants instead of hard coded strings
wsdlConstants = createObject("java", "org.apache.axis2.wsdl.WSDLConstants");

// Extract headers 
operation = ws._getServiceClient().getLastOperationContext();
context = operation.getMessageContext( wsdlConstants.MESSAGE_LABEL_IN_VALUE  );
headers = context.getProperty( context.TRANSPORT_HEADERS );

Then set the cookie and instruct the web service client to send it with subsequent requests:

if ( structKeyExists(headers, "Set-Cookie") ) {
    // include http cookies with request
    httpConstants = createObject("java", "org.apache.axis2.transport.http.HTTPConstants");
    options = ws._getServiceClient().getOptions();
    options.setManageSession( true );
    options.setProperty( httpConstants.COOKIE_STRING, headers["Set-Cookie"] );
}

// ... more requests
ws.secondMethod();
ws.thirdMethod();

NB: Side note, I noticed you are storing the instance in the shared Application scope. Just keep in mind web service instances are probably NOT thread safe.

Upvotes: 1

Eccountable
Eccountable

Reputation: 642

Inside your CFHPPT tags, set the cookie with CFHTTPPARAM

Upvotes: 0

Related Questions