No soy fanático de WSE (http://oasis-open.org/) o SOAP en general, pero puede ser útil en situaciones de integración, lo hemos usado al consumir servicios web .NET, por ejemplo .
Mi preferencia es utilizar un Application.cfc
en el mismo directorio que el servicio web para autenticar la solicitud por IP y token de seguridad o nombre de usuario/contraseña. Usamos esto para nuestros servicios web RESTful que otros consumen. Alternativamente, puede codificar la autenticación como parte del procesamiento del servicio web.
Si tiene que usar WSE, deberá agregar un montón de encabezados SOAP usando addSOAPRequestHeader()
al enviar paquetes SOAP, y luego verificar estos mismos encabezados al obtener respuestas. Esto puede ser un poco incómodo, pero aquí es un código que funciona para nosotros:
<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>
Aquí se muestra un ejemplo de uso:
// 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
) ;
Ves - un montón de código :) Espero que ayuda de todos modos.
¡Gracias por responder! Entiendo lo que hace su función, pero no estoy seguro de dónde colocarla o cómo llamarla. Estoy sirviendo mis servicios web de esta manera http://mysite.com/news.cfc?wsdl - ahora cómo obtener esta función para interceptar la llamada al cfc? Perdón por mi confusión y gracias de nuevo. – petron
He actualizado el código anterior, pero es interesante observar que nos hemos alejado de WSE con esta integración: se consideró como una fuente de problemas y no valía la pena. Ahora se autentican como parte de su solicitud de servicio en función de las credenciales de autenticación que aprobamos. –