Tôi không phải là người hâm mộ của WSE (http://oasis-open.org/) hoặc SOAP nói chung nhưng nó có thể hữu ích trong các tình huống tích hợp, chúng tôi đã sử dụng nó khi tiêu thụ các dịch vụ web .NET chẳng hạn .
Tùy chọn của tôi là sử dụng Application.cfc
trong cùng thư mục với dịch vụ web để xác thực yêu cầu theo IP và mã thông báo bảo mật hoặc tên người dùng/mật khẩu. Chúng tôi sử dụng điều này cho các dịch vụ web RESTful của chúng tôi mà những người khác sử dụng. Hoặc bạn chỉ có thể mã xác thực như là một phần của quá trình xử lý dịch vụ web.
Nếu bạn phải sử dụng WSE, bạn cần thêm một loạt tiêu đề SOAP bằng cách sử dụng addSOAPRequestHeader()
khi gửi gói SOAP, sau đó kiểm tra các tiêu đề tương tự này khi nhận phản hồi. Điều này có thể lộn xộn nhưng đây là một số mã mà làm việc cho chúng tôi:
<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>
Dưới đây là một ví dụ về sử dụng:
// 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
) ;
Bạn thấy đấy - rất nhiều mã :) Hy vọng nó giúp anyway.
Cảm ơn bạn đã trả lời! Tôi hiểu những gì chức năng của bạn làm nhưng tôi không chắc chắn chính xác nơi để đặt nó hoặc làm thế nào để gọi nó. Tôi đang phục vụ các dịch vụ web của mình như thế này http://mysite.com/news.cfc?wsdl - bây giờ làm thế nào để tôi có được chức năng này để chặn cuộc gọi đến cfc? Xin lỗi vì sự nhầm lẫn của tôi và cảm ơn một lần nữa. – petron
Tôi đã cập nhật mã ở trên, nhưng thật thú vị khi lưu ý rằng chúng tôi đã chuyển khỏi WSE bằng tích hợp này - nó được xem là một nguồn rắc rối và không đáng để nỗ lực. Bây giờ họ xác thực như là một phần của yêu cầu dịch vụ của họ dựa trên thông tin xác thực chúng tôi vượt qua. –