2011-06-22 44 views
6

Tôi đã tạo một API hiện có với các dịch vụ web bằng cách sử dụng ColdFusion sử dụng xác thực nội tuyến nhưng tôi muốn bảo mật bằng cách sử dụng một số loại xác thực nhưng tôi không biết bắt đầu từ đâu.Tạo các dịch vụ web bảo mật với ColdFusion

Dịch vụ web được tự động tạo bởi ColdFusion bằng cách thêm? Wsdl vào cuối cfcs của tôi.

Khi tôi nói "" Tôi có nghĩa là cho mỗi cuộc gọi dịch vụ web khách hàng phải vượt qua trong một chìa khóa/pass trong soapenv: cơ thể như thế này:

<apiKey xsi:type="xsd:string">test</apiKey> 
<apiPass xsi:type="xsd:string">test!ng</apiPass> 

Nhưng tôi nghĩ rằng tôi muốn sử dụng WS-Security hoặc xác thực cơ bản nhưng tôi không biết mình đang làm gì.

Dường như không có ai làm những gì tôi yêu cầu trong cộng đồng CF, điều này có vẻ kỳ quặc.

Trả lời

3

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.

+0

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

+0

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. –

Các vấn đề liên quan