I'm not a fan of WSE (http://oasis-open.org/) or SOAP in general but it can be useful in integration situations, we've used it when consuming .NET web services for example.
My preference is to use an Application.cfc
in the same directory as the web service to authenticate the request by IP and security token or username/password. We use this for our RESTful web services that others consume. Alternatively you can just code authentication as part of the web service processing itself.
If you have to use WSE you'd need to add a bunch of SOAP headers using addSOAPRequestHeader()
when sending SOAP packets, and then check these same headers when getting responses. This can be messy but here is some code that works for us:
<cffunction name="AddSecurityHeaders" access="public" returntype="any" hint="This adds the security headers as defined in the WS Security section of the WSS standard. Username and password are unencrypted." output="Yes">
<cfargument name="webSvc" required="Yes" type="any" hint="This must be a vaild web service.">
<cfargument name="username" required="Yes" type="string" hint="Username required by webservice being called.">
<cfargument name="password" required="Yes" type="string" hint="Password required by web service being called.">
<cfargument name="action" required="Yes" type="string" hint="Value to be inseted into wsa:Action node.">
<cfargument name="to" required="Yes" type="string" hint="Value to be inseted into wsa:To node.">
<cfargument name="mustUnderstandSecurityHdr" required="No" type="boolean" default="false" hint="This value will be inserted into the <wsse:Security> header as the 'mustUnderstand' value.">
<cfscript>
var rightNow = "" ;
var expiryTime = "" ;
var objXmlAction = "" ;
var objXmlMessageID = "" ;
var objXmlTo = "" ;
var objXmlSecurity = "" ;
var objXmlReplyTo = "" ;
var objTimezone = CreateObject("component", "com.utils.timezone") ;
// Setup times (UTC/GMT only!)
rightNow = objTimezone.castToUTC(Now()) ;
expiryTime = DateAdd("n", 5, rightNow) ;
// Create XML doument and add required nodes starting with <wsa:Action>
objXmlAction = XmlNew() ;
objXmlAction.XmlRoot = XmlElemNew(objXmlAction, "http://schemas.xmlsoap.org/ws/2004/03/addressing", "wsa:Action") ;
objXmlAction.XmlRoot.XmlText = ARGUMENTS.action ;
// ..then <wsa:MessageID>
objXmlMessageID = XmlNew() ;
objXmlMessageID.XmlRoot = XmlElemNew(objXmlMessageID, "http://schemas.xmlsoap.org/ws/2004/03/addressing", "wsa:MessageID") ;
objXmlMessageID.XmlRoot.XmlText = "uuid:" & CreateUUID() ;
// ...then <wsa:Address>
objXmlReplyTo = XmlNew() ;
objXmlReplyTo.XmlRoot = XmlElemNew(objXmlReplyTo, "http://schemas.xmlsoap.org/ws/2004/03/addressing", "wsa:ReplyTo") ;
objXmlReplyTo.XmlRoot.XMLChildren[1] = XmlElemNew(objXmlReplyTo, "wsa:Address") ;
objXmlReplyTo.XmlRoot.XMLChildren[1].XmlText = "http://schemas.xmlsoap.org/ws/2004/03/addressing/role/anonymous" ;
// ..then <wsa:To>
objXmlTo = XmlNew() ;
objXmlTo.XmlRoot = XmlElemNew(objXmlTo, "http://schemas.xmlsoap.org/ws/2004/03/addressing", "wsa:To") ;
objXmlTo.XmlRoot.XmlText = ARGUMENTS.to ;
// ..then the main <wsse:Security> node which contains further info...
objXmlSecurity = XmlNew(true) ;
objXmlSecurity.XmlRoot = XmlElemNew(objXmlSecurity, "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "wsse:Security") ;
// ...note: this namespace is added as it is used in children nodes and this can help avoid XmlSearch errors in CFMX
//StructInsert(objXmlSecurity.XmlRoot.XmlAttributes, "xmlns:wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd") ;
// ...Timestamp, it's children and attributes
objXmlSecurity.XmlRoot.XMLChildren[1] = XmlElemNew(objXmlSecurity, "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd", "wsu:Timestamp") ;
StructInsert(objXmlSecurity.XmlRoot.XMLChildren[1].XmlAttributes, "wsu:Id", "Timestamp-#CreateUUID()#") ;
objXmlSecurity.XmlRoot.XMLChildren[1].XmlChildren[1] = XmlElemNew(objXmlSecurity, "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd", "wsu:Created") ;
objXmlSecurity.XmlRoot.XMLChildren[1].XmlChildren[1].XmlText = DateFormat(rightNow, "YYYY-MM-DD") & "T" & TimeFormat(rightNow, "HH:mm:ss") & "Z" ;
objXmlSecurity.XmlRoot.XMLChildren[1].XmlChildren[2] = XmlElemNew(objXmlSecurity, "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd", "wsu:Expires") ;
objXmlSecurity.XmlRoot.XMLChildren[1].XmlChildren[2].XmlText = DateFormat(expiryTime, "YYYY-MM-DD") & "T" & TimeFormat(expiryTime, "HH:mm:ss") & "Z" ;
// ...Username token, attributes and children
objXmlSecurity.XmlRoot.XMLChildren[2] = XmlElemNew(objXmlSecurity, "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "wsse:UsernameToken") ;
StructInsert(objXmlSecurity.XmlRoot.XMLChildren[2].XmlAttributes, "xmlns:wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd") ;
StructInsert(objXmlSecurity.XmlRoot.XMLChildren[2].XmlAttributes, "wsu:Id", "SecurityToken-#CreateUUID()#") ;
// ...UsernameToken.Username
objXmlSecurity.XmlRoot.XMLChildren[2].XmlChildren[1] = XmlElemNew(objXmlSecurity, "wsse:Username") ;
objXmlSecurity.XmlRoot.XMLChildren[2].XmlChildren[1].XmlText = Trim(ARGUMENTS.username) ;
// ...UsernameToken.Password
objXmlSecurity.XmlRoot.XMLChildren[2].XmlChildren[2] = XmlElemNew(objXmlSecurity, "wsse:Password") ;
StructInsert(objXmlSecurity.XmlRoot.XMLChildren[2].XmlChildren[2].XmlAttributes, "Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0##PasswordText") ;
objXmlSecurity.XmlRoot.XMLChildren[2].XmlChildren[2].XmlText = Trim(ARGUMENTS.password) ;
// ... Nonce
objXmlSecurity.XmlRoot.XMLChildren[2].XmlChildren[3] = XmlElemNew(objXmlSecurity, "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "wsse:Nonce") ;
objXmlSecurity.XmlRoot.XMLChildren[2].XmlChildren[3].XmlText = ToBase64(CreateUUID()) ;
// ...Created
objXmlSecurity.XmlRoot.XMLChildren[2].XmlChildren[4] = XmlElemNew(objXmlSecurity, "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd", "wsu:Created") ;
objXmlSecurity.XmlRoot.XMLChildren[2].XmlChildren[4].XmlText = DateFormat(rightNow, "YYYY-MM-DD") & "T" & TimeFormat(rightNow, "HH:mm:ss") & "Z" ;
// Add the created headers to the soap requests - note that the 2nd and 3rd parameters have no significance in this instance
addSOAPRequestHeader(ARGUMENTS.webSvc, "sia1", "hd1", "#objXmlAction#", false) ;
addSOAPRequestHeader(ARGUMENTS.webSvc, "sia1", "hd1", "#objXmlMessageID#", false) ;
addSOAPRequestHeader(ARGUMENTS.webSvc, "sia1", "hd1", "#objXmlReplyTo#", false) ;
addSOAPRequestHeader(ARGUMENTS.webSvc, "sia1", "hd1", "#objXmlTo#", false) ;
addSOAPRequestHeader(ARGUMENTS.webSvc, "sia1", "hd1", "#objXmlSecurity#", ARGUMENTS.mustUnderstandSecurityHdr) ;
return ARGUMENTS.webSvc ;
</cfscript>
</cffunction>
Here is an example of use:
// Create web service
objWebSvc = CreateObject("webservice", "remoteWebService?WSDL") ;
// Create security object and add the security header to our SOAP request
objWSESecurity = CreateObject("component", "wse") ;
objWebSvc = objWSESecurity.AddSecurityHeaders(
webSvc=objWebSvc,
username="xxx",
password="yyy",
action="remoteAction",
to="remoteWebService",
mustUnderstandSecurityHdr=false
) ;
You see - lots of code :) Hope it helps anyway.