ADFS的WS-Trust示例

Ws-Trust,是基于XML WebService安全的一个规范,它扩展了WS-Security。

WS-Security定义了系统之间在调用WebService的时候如何在SOAP Header中嵌入Token,如UserNameToken,X509证书,SAML,Kerberos等等,这些介绍可以看 https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=wss

Ws-Security仅仅定义了Token使用的方式,Ws-Trust则定义了系统之间请求和获取Token的框架(也包括了Broker中介信任关系),但是流程图在规范中并没有,倒是在WS-Federation中有不少,见下图:



WS-*包括一系列标准,如WS-Security, WS-policy, WS-Federation, WS-SecurityPolicy, WS-metadataExchange。。。这是一个学习英文阅读理解的好去处。。。这些标准由微软主推,当然也包括IBM,Oracle等等,ADFS是业界很出名的负责Authentication&Authorization的IDP(Identity Provider),下面就是用SOAP UI,基于WS-Trust和ADFS进行交互的例子。

基本需求:我们现在正在做一个STS,要有一个Token Exchange的功能,桌面程序需要从ADFS获取一个SAML Token,但是程序并不需要知道这个Token是什么,把这个SAML Token交给我们在做的STS,STS会解析这个Token,返回我们自己定义的Token给客户端。
解决的流程如下:

1. Client(非浏览器)先发送一个RST(Request Security Token)到ADFS,其中会包含用户名,密码:

URL: https://YOUR_ADFS_URL/adfs/services/trust/13/usernamemixed
Method: Post
Header: Content-Type: application/soap+xml;
Body:
<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"
	xmlns:a="http://www.w3.org/2005/08/addressing"
	xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
	<s:Header>
		<a:Action s:mustUnderstand="1">http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Issue</a:Action>
		<a:To s:mustUnderstand="1">https://server.com/adfs/services/trust/13/UsernameMixed</a:To>
		<o:Security s:mustUnderstand="1"
			xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
			<o:UsernameToken u:Id="uuid-6a13a244-dac6-42c1-84c5-cbb345b0c4c4-1">
				<o:Username>YOUR_USER_NAME</o:Username>
				<o:Password
					Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">YOUR_PASSWORD</o:Password>
			</o:UsernameToken>
		</o:Security>
	</s:Header>
	<s:Body>
		<trust:RequestSecurityToken
			xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">
			<wsp:AppliesTo xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
				<a:EndpointReference>
					<a:Address>YOUR_RELYING_PARTY_URL</a:Address>
				</a:EndpointReference>
			</wsp:AppliesTo>
			<trust:KeyType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/Bearer</trust:KeyType>
			<trust:RequestType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue</trust:RequestType>
			<trust:TokenType>urn:oasis:names:tc:SAML:2.0:assertion</trust:TokenType>
		</trust:RequestSecurityToken>
	</s:Body>
</s:Envelope>



2. ADFS会返回一个RSTR(Request Security Token Response)给Client,RSTR的格式如下,关键部分已经被打码:
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
   <s:Header>
      <a:Action s:mustUnderstand="1">http://docs.oasis-open.org/ws-sx/ws-trust/200512/RSTRC/IssueFinal</a:Action>
      <o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
         <u:Timestamp u:Id="_0">
            <u:Created>2016-11-21T09:22:49.559Z</u:Created>
            <u:Expires>2016-11-21T09:27:49.559Z</u:Expires>
         </u:Timestamp>
      </o:Security>
   </s:Header>
   <s:Body>
      <trust:RequestSecurityTokenResponseCollection xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">
         <trust:RequestSecurityTokenResponse>
            <trust:Lifetime>
               <wsu:Created xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">2016-11-21T09:22:49.554Z</wsu:Created>
               <wsu:Expires xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">2016-11-21T10:22:49.554Z</wsu:Expires>
            </trust:Lifetime>
            <wsp:AppliesTo xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
               <wsa:EndpointReference xmlns:wsa="http://www.w3.org/2005/08/addressing">
                  <wsa:Address>****************************************</wsa:Address>
               </wsa:EndpointReference>
            </wsp:AppliesTo>
            <trust:RequestedSecurityToken>
               <EncryptedAssertion xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
                  <xenc:EncryptedData Type="http://www.w3.org/2001/04/xmlenc#Element" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
                     <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc"/>
                     <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
                        <e:EncryptedKey xmlns:e="http://www.w3.org/2001/04/xmlenc#">
                           <e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p">
                              <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
                           </e:EncryptionMethod>
                           <KeyInfo>
                              <ds:X509Data xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
                                 <ds:X509IssuerSerial>
                                   *****************************
                                 </ds:X509IssuerSerial>
                              </ds:X509Data>
                           </KeyInfo>
                           <e:CipherData>
                              <e:CipherValue>********************************</e:CipherValue>
                           </e:CipherData>
                        </e:EncryptedKey>
                     </KeyInfo>
                     <xenc:CipherData>
                        <xenc:CipherValue>********************************</xenc:CipherValue>
                     </xenc:CipherData>
                  </xenc:EncryptedData>
               </EncryptedAssertion>
            </trust:RequestedSecurityToken>
            <trust:RequestedAttachedReference>
               <SecurityTokenReference b:TokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:b="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd">
                  <KeyIdentifier ValueType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLID">_92b3ec38-838c-402c-b335-f64ed16722a1</KeyIdentifier>
               </SecurityTokenReference>
            </trust:RequestedAttachedReference>
            <trust:RequestedUnattachedReference>
               <SecurityTokenReference b:TokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:b="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd">
                  <KeyIdentifier ValueType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLID">_92b3ec38-838c-402c-b335-f64ed16722a1</KeyIdentifier>
               </SecurityTokenReference>
            </trust:RequestedUnattachedReference>
            <trust:TokenType>urn:oasis:names:tc:SAML:2.0:assertion</trust:TokenType>
            <trust:RequestType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue</trust:RequestType>
            <trust:KeyType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/Bearer</trust:KeyType>
         </trust:RequestSecurityTokenResponse>
      </trust:RequestSecurityTokenResponseCollection>
   </s:Body>
</s:Envelope>


3. 发送另外一个RST到我们要做的STS,格式如1,把步骤2中获得的EncryptedAssertion作为Security Header,Token Type换成我们自己的Token type。

4. 我们解析Security Header中加密的SAML Token,提取用户信息,生成新的Token,放在RSTR中返回给客户。


这里仅仅记录了通过HTTP Call完成这些流程的大致步骤,.Net很容易用代码实现这些,微软把这些东西都集成在了FrameWork里(不知道这样描述对不对,从JAVA角度看就是JDK提供了API,不需要使用第三方类库),可以直接有API调用的。JAVA就比较麻烦,现在CXF通过WSS4j实现了部分WS-*标准,可以在项目中引用进来通过代码实现。

猜你喜欢

转载自wwwcomy.iteye.com/blog/2339725