当前位置: 首页 > 工具软件 > ws-http > 使用案例 >

ADFS的WS-Trust示例

尉迟栋
2023-12-01
Ws-Trust,是基于XML WebService安全的一个规范,它扩展了WS-Security。

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

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

[img]http://dl2.iteye.com/upload/attachment/0121/4360/611f1422-ae95-37bc-a66b-8908bbb5a4b3.jpg[/img]

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-*标准,可以在项目中引用进来通过代码实现。
 类似资料: