安全性是我們大多數客戶優先考慮的問題。隨著越來越多的客戶采用Web服務,他們發現,他們需要了解如何保護Web服務,以及使用何種身份驗證機制。為了保持Web服務的開放性并支持多種客戶端類型,就必須了解如何處理Web服務的安全性問題。 本文深入幕后探討了WebLogic Web服務的安全性問題。我將闡明如何保護WebLogic Web服務,身份驗證如何工作,以及如何使用各種編程語言開發客戶端來為WebLogic Web服務提供身份驗證。 以WebLogic Server作為宿主的Web服務是使用標準的J2EE組件(比如EJB和JMS)來實現的,并且作為標準的J2EE企業應用程序來打包。WebLogic Web服務使用簡單對象訪問協議(Simple Object Aclearcase/" target="_blank" >ccess Protocol ,SOAP)1.1作為消息格式,并使用HTTP 1.1作為連接協議。 Web服務運行時組件是一組創建Web服務所需的servlet和相關的基礎架構。運行時的元素之一是一組用于處理來自客戶端SOA請求的servlet。這些servlet包含在WebLogic Server發布中。運行時的另一個元素是Ant任務,它負責生成和組裝WebLogic Web服務的所有組件。 WebLogic Web服務作為標準的J2EE企業應用程序來打包,它由以下特殊組件組成: 在一個RPC風格的Web服務中,無狀態會話EJB可以完成Web服務的所有實際工作,或者它們可以把工作分配給其他EJB。Web服務的實現者決定哪些EJB完成實際工作。在消息風格的Web服務中,J2EE對象(通常是消息驅動bean)從JMS目的地獲取消息,并且處理它們。WebLogic Web服務作為企業存檔(.ear)文件打包,其中包含Web應用程序的Web存檔(.war)文件和EJB存檔(.jar)文件。 因為WebLogic Web服務作為標準的J2EE企業應用程序打包,所以通過保護組成Web服務的以下標準J2EE組件中的一些或全部,來保護對Web服務的訪問: 可以通過保護負責處理客戶端和服務之間SOAP消息的SOAP servlet,來保護消息風格的Web服務。 不論是手動還是使用wsgen Ant任務來組裝Web服務時,您都可以在Web應用程序的web.xml文件中引用SOAP servlet。這些servelet負責處理在WebLogic Server和客戶端應用程序之間傳遞的SOA消息。它們始終部署在WebLogic Server上,并為所有部署的WebLogic Web服務所共享。 Web服務引用哪個特定SOAP servlet取決于它的類型(RPC風格還是消息風格)。下面列出了對每個SOAP servlet的描述: 為了限制對DestinationSendAdapter SOAP servlet的訪問,您首先定義一個角色,并把它映射到安全域中的一個或多個主體,然后通過把web-resources-collection元素中的如下url-pattern元素添加到Web應用程序的web.xml部署描述器,指定把該安全約束應用到該SOAP servlet。 <url-pattern>/sendMsg</url-pattern> 您可以限制對RPC風格的Web服務的訪問,具體方法是限制對實現Web服務或SOAP servlet的無狀態會話EJB的訪問。清單2和3顯示了如何設置web.xml和weblogic.xml文件以保護SOAP servlet。確??蛻舳巳匀荒軌蛟L問WSDL文件。為了確保這一點,應避免使用通配符映射;而是顯式地保護SOAP servlet適配器路徑。這兩個清單提供了一個如何保護帳戶管理程序代理Web服務的例子。正如您所看到的那樣,角色是在web.xml中定義的,并與域中的組相關聯。 為了理解如何處理Web服務客戶端的安全性問題,必須要理解SOAP和HTTP身份驗證的工作方式。 Web服務使用SOAP協議,它是以一些底層傳輸機制為基礎而實現的高級消息傳送協議。Web服務安全性仍然是一個新興領域,圍繞SOAP規范出現了一些擴展,以支持安全功能。當前,SOAP使用的是針對身份驗證的底層傳輸協議基礎架構。所以,WebLogic Server SOAP間接地使用了HTTP 1.1身份驗證。 使用HTTP的用戶身份驗證方法十分簡單。因為HTTP是一個無狀態協議--也就是說,一旦請求完成之后,服務器不會記住關于該請求的任何信息--瀏覽器需要為每個請求重新發送用戶名和密碼(參見圖1)。 第一次訪問需驗證的資源時,服務器將返回401狀態(“Unauthorized”),并包括一個WWW身份驗證的響應頭,用于指明所使用的域名和身份驗證模式。然后,瀏覽器應該要求用戶輸入用戶名和密碼。接著,它再次請求同樣的資源,這次包括了一個含有模式名(“Basic”)的身份驗證頭,以及輸入的用戶名和密碼。服務器檢查此用戶名和密碼,如果它們是有效的,就會返回相應的頁面。如果密碼對于該用戶無效,或者用戶沒有訪問權限,服務器還會像以前一樣返回401狀態。然后,瀏覽器可以要求用戶嘗試重新輸入用戶名和密碼。 假定用戶名和密碼有效,接下來用戶可能會請求一個受保護的資源。在這種情況下,服務器將使用401狀態作為響應,而瀏覽器能夠使用用戶和密碼詳細信息再次發送請求。這樣做會很慢,然而對于隨后的請求,瀏覽器就會改為發送身份驗證頭。要了解HTTP身份驗證方面的更多信息,請參考W3C HTTP Working Group RFC 2617 (www.w3c.org/Protocols/Specs.html)。 雖然前面的部分著重于瀏覽器客戶端,但是協議對于任何類型的客戶端都是相同的。任何需要訪問受保護的Web服務的客戶端都要理解這個HTTP身份驗證協議,并實現它以求通過身份驗證。這個部分說明了如何傳送來自各種類型客戶端的身份驗證信息。 Microsoft為傳輸層提供HTTPConnector接口。它使用兩個屬性來傳遞證書--AuthUser 和AuthPassword。清單4顯示了一個使用Visual Basic和MS SOAP Toolkit 2.0調用一個受保護的WebLogic Web服務的例子。 不應該把AuthUser 和AuthPassword與ProxyUser 和ProxyPassword相互混淆。它們用于為代理服務器提供證書(如果存在證書的話)。這種身份驗證的工作方式是一樣的,除了返回的錯誤號是407,而不是401。 WebLogic Server提供Java客戶端庫來訪問受保護的資源。用戶名和證書是使用"java.naming.security.principal"和 "java.naming.security.credentials"來傳送的。清單5描述了Java客戶端如何使用WebServiceProxy來調用一個受保護的WebLogic Web服務。 JAX-RPC(Java API for XML-based remote procedure calls,用于基于XML的遠程過程調用的Java API)是2002年6月發布的新標準,它定義了用于調用Web服務的API。WebLogic Server 7.0 支持 JAX-RPC。JAX-RPC接口"Stub"和 "Call"均支持屬性”javax.xml.rpc.security.auth.username" 和 "javax.xml.rpc.security.auth.password",身份驗證信息就是借助這兩個屬性進行傳送的。您還可以使用靜態常量Stub.USERNAME_PROPERTY 和Stub.PASSWORD_PROPERTY在調用服務之前設置安全性信息(參見清單6)。還可以在使用get<web service>port()獲得端口的同時傳送用戶名和密碼。 類似地,您可以使用廠商提供的API編寫C/C++客戶端。MS SOAP工具包可以用于編寫Windows平臺上的C++客戶端。用戶名和密碼是使用Connector Property進行傳送的。下面是一個設置用戶名和密碼的例子。 本文討論了用于WebLogic Web服務和保護Web服務組件的身份驗證。因為Web服務是涉及到不同技術的異構環境的自然選擇,必須了解如何使用各種類型的客戶端訪問受保護的Web服務。 WebLogic Web 服務組件
保護WebLogic Web 服務
保護消息風格的Web服務
例如,在客戶端應用程序用來發送數據給JMS目的地的消息風格的Web服務中,負責處理SOAP消息的SOAP servlet是weblogic.soap.server.servlet.DestinationSendAdapter。用于組裝Web服務的wsgen Ant任務把清單1中所示的元素添加到Web應用程序的web.xml部署描述器。 清單1
<servlet>
<servlet-name>sender</servlet-name>
<servlet-class>
weblogic.soap.server.servlet.DestinationSendAdapter
</servlet-class>
<init-param>
<param-name>topic-resource-ref</param-name>
<param-value>senderDestination</param-value>
</init-param>
<init-param>
<param-name>connection-factory-resource-ref</param-name>
<param-value>senderFactory</param-value>
</init-param>
</servlet>
... 保護RPC風格的Web服務
清單2
<security-constraint>
<web-resource-collection>
<web-resource-name> Weather</web-resource-name>
<url-pattern>/weatherturi/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>Admin</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
</login-config>
<security-role>
<role-name>Admin</role-name>
</security-role>
清單3
<security-role-assignment>
<role-name>Admin</role-name>
<principal-name>system</principal-name>
</security-role-assignment>
Web 服務客戶端
SOAP身份驗證
HTTP身份驗證
圖1 客戶端類型
MS Visual Basic 客戶端
清單4
Set Client = New SoapClient
Client.mssoapinit "<WSDL URL>", "<Service Name in WSDL>", "<Port Name in WSDL>"
Connect
Client.ConnectorProperty("AuthUser") = <username>
Client.ConnectorProperty("AuthPassword") = <password>
Client.<Service(args)>
Java客戶端
清單5
Properties h = new Properties();
h.put(Context.INITIAL_CONTEXT_FACTORY,
"weblogic.soap.http.SoapInitialContextFactory");
h.put("java.naming.security.principal", "<username>" );
h.put("java.naming.security.credentials", "<password>" );
Context context = new InitialContext(h);
WebServiceProxy proxy = (WebServiceProxy)context.lookup(<WSDL_URL>);
SoapMethod method = proxy.getMethod("<method name>");
method.invoke(new Object[]{"<args>"});
JAX-RPC客戶端
清單6
<Web Service Stub>._setProperty(Stub.USERNAME_PROPERTY, "<username>");
<Web Service Stub>._setProperty(Stub.PASSWORD_PROPERTY, "<password>");
MS C++ 客戶端
Connector->Property["AuthUser"] =
"<UserName>";
Connector->Property["AuthPassword"] = "<Password>";
結束語
原文轉自:http://www.anti-gravitydesign.com