在分別介紹了XML Signature和XML Encryption後,我們瞭解瞭如何用XML的形式來保證消息的完整性(Integrity)和機密性(Confidentiality)。如何將其運用到Web Service中從而保證Web Service的安全性,這就是WS-Security規範所描述的內容。我們知道Web Service的採用SOAP作爲消息封裝協議, 因此WS-Security規範主要描述瞭如何將XML Security(XML Signature和XML Encryption)與已有的安全技術(Kerberos,X.509,SAML)結合, 並把它們綁定到SOAP中.
<S:Envelope>
<S:Header>
<wsse:Security>
<!-- Security Token -->
<wsse:UsernameToken>
...
</wsse:UsernameToken>
<!-- XML Signature -->
<ds:Signature>
...
<ds:Reference URI="#body">
...
</ds:Signature>
<!-- XML Encryption Reference List -->
<xenc:ReferenceList>
<xenc:DataReference URI="#body"/>
</xenc:ReferenceList>
</wsse:Security>
</S:Header>
<S:Body>
<!-- XML Encrypted Body -->
<xenc:EncryptedData Id="body" Type="content">
...
</xenc:EncryptedData>
</S:Body>
</S:Envelope>
以上是一個典型的使用WS-Security協議來保證SOAP消息安全的例子。從中可以看出WS-Security協議主要對SOAP消息的Head部分做了擴展---加入了wsse:Security元素。其中針對安全的三個方面Authentication, Integrity, Confidentiality分別定義了Security Token, XML Signature以及XML Encryption Reference List三個子元素。而在SOAP包中的需要加密的業務內容(通常會加密整個Soap Body)被經過XML Encryption處理過的元素(EncryptedDate)所替代。
下面這張圖大致描述了WS-Security所包含的元素以及它們之間的關係。
(注意這幅圖只是一張示意圖,比如ds:Signature也可以對Soap Head中的元素做簽名)
從之前對XML Signature和XML Encryption介紹中,我們已經瞭解了簽名和加密的具體過程,以及在整個過程中產生的各個元素的含義。下面就從一個具體的運用了WS-Security規範的Soap Envelop中來看看如何在WS-Security中使用XML Signature和XML Encryption。
<?xml version="1.0" encoding="utf-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2001/12/soap-envelope"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
xmlns:xenc="http://www.w3.org/2001/04/xmlenc"
xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility">
<SOAP-ENV:Header>
<wsse:Security
xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/secext">
<wsse:UsernameToken wsu:Id="UserToken">
<wsse:Username>HotelService</wsse:Username>
<wsse11:Salt>sdfer..</wsse11:Salt>
<wsse11:Iteration>1000</wsse11:Iteration>
</wsse:UsernameToken>
<ds:Signature>
<ds:SignedInfo>
<ds:CanonicalizationMethod
Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<ds:SignatureMethod
Algorithm="http://www.w3.org/2000/09/xmldsig#hmac-sha1"/>
<ds:Reference URI="#DiscountedBookingForPartnersResponse">
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>JwFsd3eQc0iXlJm5PkLh7...</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>BSxlJbSiFdm5Plhk...</ds:SignatureValue>
<ds:KeyInfo>
<wsse:SecurityTokenReference>
<wsse:Reference URI="#UserToken"/>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
</ds:Signature>
<xenc:ReferenceList>
<xenc:DataReference URI="#DiscountResponse"/>
</xenc:ReferenceList>
</wsse:Security>
</SOAP-ENV:Header>
<SOAP-ENV:Body wsu:Id="DiscountedBookingForPartnersResponse">
<s:GetSpecialDiscountedBookingForPartnersResponse
xmlns:s=?http://www.MyHotel.com/partnerservice?>
<xenc:EncryptedData
wsu:Id="DiscountResponse"
type="http://www.w3.org/2001/04/xmlenc#Element">
<xenc:EncryptionMethod
Algorithm="http://www.w3.org/2001/04/xmlenc#aes256_cbc "/>
<ds:KeyInfo xmlns:ds='http://www.w3.org/2000/09/xmldsig#'>
<wsse:SecurityTokenReference>
<wsse:Reference URI="#UserToken"/>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
<CipherData>
<CipherValue>XDsFaDWsHdhrHdhcW0x...</CipherValue>
</CipherData>
</xenc:EncryptedData>
</s:GetSpecialDiscountedBookingForPartnersResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
對於其中的大部分元素我們已經比較熟悉,而wsse:UsernameToken以及在ds:Signature和xenc:EncryptedData 中出現的wsse:SecurityTokenReference子元素則顯得比較陌生。
我們知道爲了保證消息的完整性和機密性需要用到密鑰(對稱或非對稱),而在它們各自的ds:KeyInfo子元素中都使用wsse:SecurityTokenReference引用到了在Soap Head最開始定義的Security Token(這裏是UsernameToken)。由此可以看出Security Token是保證消息的完整性和機密性的基礎,同時密鑰也是用戶證明身份的標誌,因此包含密鑰信息的Security Token也是實現身份鑑別的基礎。在已經介紹過XML Signature和XML Encryption的基礎上,下面對WS-Security的介紹將主要集中在Security Token上。