Richie

Sometimes at night when I look up at the stars, and see the whole sky just laid out there, don't you think I ain't remembering it all. I still got dreams like anybody else, and ever so often, I am thinking about how things might of been. And then, all of a sudden, I'm forty, fifty, sixty years old, you know?

WSE 3.0 UsernameToken SOAP消息分析

    WSE 3.0 UsernameToken应用中的例子,一个调用HelloWorld() Web Service示例,应用了WSE 3.0 UsernameToken方式,下面对照不同的配置下SOAP消息的差异。

    1. 未使用WSE时的SOAP消息。
<soap:Envelope ... >
  
<soap:Body>
    
<HelloWorld xmlns="http://tempuri.org/" />
  
</soap:Body>
</soap:Envelope>

    2. 启用WSE,使用UsernameToken,但不启用WS-Security 1.1 Extensions(UsernameOverTransportAssertion)。
    SOAP消息如下:
<soap:Envelope ... >
  
<soap:Header>
    
<wsa:Action>http://tempuri.org/HelloWorld</wsa:Action>
    
<wsa:MessageID>urn:uuid:b637fb86-8712-4845-a71c-8f91320168ac</wsa:MessageID>
    
<wsa:ReplyTo>
      
<wsa:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:Address>
    
</wsa:ReplyTo>
    
<wsa:To>http://.../WSEServer/MyService.asmx</wsa:To>
    
<wsse:Security soap:mustUnderstand="1">
      
<wsu:Timestamp wsu:Id="Timestamp-72b13f43-5c2e-46ea-81cb-dbc0f99b3605">
        
<wsu:Created>2007-03-15T04:47:47Z</wsu:Created>
        
<wsu:Expires>2007-03-15T04:52:47Z</wsu:Expires>
      
</wsu:Timestamp>
      
<wsse:UsernameToken xmlns:wsu="......" wsu:Id="SecurityToken-a2526d47-d01b-476c-a15b-b7f84e55181d">
        
<wsse:Username>Administrator</wsse:Username>
        
<wsse:Password Type="......">5W0xOMVVDnlCRwclYMszo9ZEwOs=</wsse:Password>
        
<wsse:Nonce>ttsA3uaB4KqBa2Vrcd7X8A==</wsse:Nonce>
        
<wsu:Created>2007-03-15T04:47:47Z</wsu:Created>
      
</wsse:UsernameToken>
    
</wsse:Security>
  
</soap:Header>
  
<soap:Body>
    
<HelloWorld xmlns="http://tempuri.org/" />
  
</soap:Body>
</soap:Envelope>
    wsa:的节点是WS-Addressing内容,wsse:Security节点里面就是WSE安全性扩展的内容了,包括了UsernameToken认证信息,密码经过了加密处理。WS-Addressing可参考:WS-Addressing 从理论到实践

    3. 在WS-Security 1.1扩展中选择Sign-Only选项(UsernameForCertificateAssertion)。
完整的SOAP消息内容
    主要元素结构如下:
<soap:Envelope ... >
  
<soap:Header>
    
<wsa:Action wsu:Id="Id-7b15dc35-0eb2-4df7-890c-79b3e3b70917">http://tempuri.org/HelloWorld</wsa:Action>
    
<wsa:MessageID wsu:Id="Id-3867fb2e-3f70-4ab8-9c71-1051104fc7e5">urn:uuid:...</wsa:MessageID>
    
<wsa:ReplyTo wsu:Id="Id-b7e40812-850d-4de6-b2a1-511a8661c526">...</wsa:ReplyTo>
    
<wsa:To wsu:Id="Id-6528e50b-b801-487d-bce8-8d016064490e">http://.../WSEServer/MyService.asmx</wsa:To>
    
<wsse:Security soap:mustUnderstand="1">
      
<wsu:Timestamp wsu:Id="Timestamp-a74f13f4-f22a-4891-9f6c-305453df2170">...</wsu:Timestamp>
      <xenc:EncryptedKey Id="SecurityToken-6154d45b-e47f-4ee2-bc30-c70c655ecca0" xmlns:xenc="...">
        
<xenc:EncryptionMethod Algorithm="...">
          
<ds:DigestMethod ... />
        
</xenc:EncryptionMethod>
        
<KeyInfo xmlns="...">
          
<wsse:SecurityTokenReference>
            
<wsse:KeyIdentifier ValueType="..." EncodingType="...">RRQNS/KyeQtEHDwaaEgaymxsxpo=</wsse:KeyIdentifier>
          
</wsse:SecurityTokenReference>
        
</KeyInfo>
        
<xenc:CipherData>
          
<xenc:CipherValue>...</xenc:CipherValue>
        
</xenc:CipherData>
      
</xenc:EncryptedKey>
      
<!--派生密匙1-->
      
<wssc:DerivedKeyToken wsu:Id="SecurityToken-1bcf5e7d-34ad-429d-93f5-d2818446418e" ...>
        
<wsse:SecurityTokenReference>
          <wsse:Reference URI="#SecurityToken-6154d45b-e47f-4ee2-bc30-c70c655ecca0" ... />
        
</wsse:SecurityTokenReference>
        
<wssc:Generation>0</wssc:Generation>
        
<wssc:Length>32</wssc:Length>
        
<wssc:Label>WS-SecureConversationWS-SecureConversation</wssc:Label>
        
<wssc:Nonce>SetU9IzX1rRSG0jTjtBZMw==</wssc:Nonce>
      
</wssc:DerivedKeyToken>
      
<xenc:ReferenceList xmlns:xenc="...">...</xenc:ReferenceList>
      
<xenc:EncryptedData Id="Enc-b1232155-f376-4ff7-9521-6f66e8a2acc7" type="http://www.w3.org/2001/04/xmlenc#Element" ...>
        
<xenc:EncryptionMethod Algorithm="..." />
        
<!--使用派生密匙1加密-->
        
<KeyInfo xmlns="...">
          
<wsse:SecurityTokenReference>
            
<wsse:Reference URI="#SecurityToken-1bcf5e7d-34ad-429d-93f5-d2818446418e" ValueType="..." />
          
</wsse:SecurityTokenReference>
        
</KeyInfo>
        
<xenc:CipherData>
          
<xenc:CipherValue>...</xenc:CipherValue>
        
</xenc:CipherData>
      
</xenc:EncryptedData>
      
<!--派生密匙2-->
      
<wssc:DerivedKeyToken wsu:Id="SecurityToken-7b9ff86e-8d7d-430a-ac0b-1a330d036d1c" ...>...</wssc:DerivedKeyToken>
      
<Signature xmlns="...">
        
<SignedInfo>
          
<ds:CanonicalizationMethod ... />
          
<SignatureMethod Algorithm="..." />
          
<Reference URI="#SecurityToken-b25e7443-682b-479b-be6f-dd61c9f38e82">...</Reference>
          
<Reference URI="#Id-7b15dc35-0eb2-4df7-890c-79b3e3b70917">...</Reference>
          
<Reference URI="#Id-3867fb2e-3f70-4ab8-9c71-1051104fc7e5">...</Reference>
          
<Reference URI="#Id-b7e40812-850d-4de6-b2a1-511a8661c526">...</Reference>
          
<Reference URI="#Id-6528e50b-b801-487d-bce8-8d016064490e">...</Reference>
          
<Reference URI="#Timestamp-a74f13f4-f22a-4891-9f6c-305453df2170">...</Reference>
          
<Reference URI="#Id-657b476d-f5a5-4d60-9476-9ae7087caad6">...</Reference>
        
</SignedInfo>
        
<SignatureValue>xL7BlslQN8GrE3E9IPaSzoMcu5Y=</SignatureValue>
        
<KeyInfo>
          
<!--使用派生密匙2签名-->
          
<wsse:SecurityTokenReference>
            
<wsse:Reference URI="#SecurityToken-7b9ff86e-8d7d-430a-ac0b-1a330d036d1c" ValueType="..." />
          
</wsse:SecurityTokenReference>
        
</KeyInfo>
      
</Signature>
    
</wsse:Security>
  
</soap:Header>
  
<soap:Body wsu:Id="Id-657b476d-f5a5-4d60-9476-9ae7087caad6">
    
<HelloWorld xmlns="http://tempuri.org/" />
  
</soap:Body>
</soap:Envelope>
    大致看一下这段SOAP消息的含义:
    a) xenc:EncryptedKey元素中是经过加密处理后UsernameToken中的用户密码,使用服务器端X.509证书的公匙加密。
    b) 接下来可以看到有两个wssc:DerivedKeyToken元素,这是生成的两个派生密匙,关于派生密匙可以参考Web服务安全对话语言
    wssc:DerivedKeyToken/wsse:SecurityTokenReference/wsse:Reference元素的URI属性值是xenc:EncryptedKey的id,表明它对xenc:EncryptedKey元素的引用,从这个引用可以知道是从哪个密匙派生而来。通过URI属性引用其它资源,如果以符号#开始,表明是引用当前xml文档中id、wsu:id值相对应的元素。
    c) xenc:EncryptedData元素。从xenc:EncryptedData元素的type属性可以看出它是对原SOAP消息中的一个xml元素进行了加密,是哪一个元素呢,就是类似步骤2中的那个wsse:UsernameToken元素,它包含用户名等安全认证信息。通过xenc:EncryptedData/KeyInfo里面的引用信息可以知道,这个元素是使用派生密匙1加密的。
    d) Signature元素。可以参考:XML Signature
    从Signature/KeyInfo中的引用信息可以知道,使用了派生密码2进行签名。通过Signature/SignedInfo中的Reference列表可以知道,SOAP消息中的哪些元素被用来签名了。在前面完整的SOAP消息中你可能会发现,第一个Reference元素URI属性所指向的id在文档中不存在。在c)中提到xenc:EncryptedData元素对原SOAP文档的一个元素进行了加密,这个元素的id应当就是被第一个Reference引用的。

    4. 在WS-Security 1.1扩展中选择Sign and Encrypt选项(UsernameForCertificateAssertion)。
    在这个配置中,soap:Header和步骤3 Sign-Only配置时基本一样,区别是,步骤3的配置中soap:Body没有被加密,而选择Sign and Encrypt选项后soap:Body也是被加密的。如果基于步骤3的SOAP消息来看,soap:Body使用的派生密匙1进行加密。
    soap:Body的xml如下:
  <soap:Body wsu:Id="Id-d964042a-68fe-4c48-a0e1-480863f0d4c5">
    
<xenc:EncryptedData Id="Enc-146fe92b-0887-440a-a52d-58dce539f25e" ...>
      
<xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc" />
      
<KeyInfo xmlns="...">
        
<wsse:SecurityTokenReference>
          
<wsse:Reference URI="#SecurityToken-9682679a-876c-4096-992b-068dd5752d91" ValueType="..." />
        
</wsse:SecurityTokenReference>
      
</KeyInfo>
      
<xenc:CipherData>
        
<xenc:CipherValue>...</xenc:CipherValue>
      
</xenc:CipherData>
    
</xenc:EncryptedData>
  
</soap:Body>

posted on 2007-03-16 16:00  riccc  阅读(5043)  评论(13编辑  收藏  举报

导航