1、 Sts介绍WSS
STS 是一个基于ws-trust 的一种服务。它基于ws-trust 在web service consumer 和 web service provider 之间交换token令牌。通过这个相互信任的令牌token,达到service provider 和 service consumer 之间的信任。
(注释:Ws_trust,是什么呢。WS-Trust是WS-*规范族中的一员,也是OASIS(Organization for the Advancement of Structured Information Standards)其中的一项标准。它对WS-Security规范提供了一些扩展,专门处理有关安全tokens的发布,整新和验证,确保各方参与者的互操作处在一个可信任的安全数据交换环境中。WS-Trust规范发起于一些有代表性的公司,最后于2007年3月被OASIS核准通过并作为一项标准发布。通过使用WS-Trust中定义的这些扩展规范,可以确保工作在Web服务框架中的Web应用之间的通信是安全的。WS-*簇主要是由ws-fedearation,即web服务联邦语言定义的ws-security(使用soap与ws-security扩展的 标准,将安全声明和安全上下文同soap绑定),ws-policy(安全策略),ws-trust,ws-secureconvertion(建立和共享上下文)等规范)
Sts达到的安全模型可以实现如下的一些目的:
1、Web 服务可以要求进来的消息证明一组 声明(token)(例如,名称、密钥、许可、性能等等)。如果消息到达但没有必需的声明,那么服务可以忽略或者拒绝该消息。我们把这一组必需的声明和相关的信息称为 策略。
2、请求者可以通过把 安全性令牌与消息关联起来发送带必需声明的证明的消息。这样,消息既要求特定的操作又要证明它们的发送者具有要求该操作的声明。
3、如果请求者没有必需的声明,那么请求者或它们的代表可以通过与其它 Web 服务联系设法获得必需的声明。这些其它的 Web 服务,我们称其为 安全性令牌服务(security token service),可以接下来要求它们自己的一组声明。安全性令牌服务通过签发安全性令牌代理不同信任域之间的信任。
STS主要功能:
验证进入某安全域的用户的凭证、评估提交的安全令牌的信任,担当身份提供者。
Issue(发布安全令牌) 、 Validate(验证安全令牌)、Renew(更新安全令牌) 和 Cancel(取消安全令牌)以及exchange(交换安全令牌)。
Web服务安全联合构架定义了两个一般的请求者:被动和主动。
被动一般是传统的基于http的web浏览器。主动呢,请求者必须主动要求需要什么样的令牌,如何嵌入到soap协议中等等。
举一个跨域sso的过程,说明主动和被动的区别:
被动联合方案基于 WS-Federation 被动请求者配置文件,其中涉及基于浏览器的通信。虽然底层消息传递仍基于 WS-Trust,但 RST 却在 STS URL 中被分解为查询字符串参数,而 RSTR 通常会作为表单参数被发布到 RP。被动 STS 和 RP 使用联合 Web 处理程序来截取这些参数。被动 STS 可以直接处理 WS-Trust 请求,或者将其传递到底层 WS-Trust 实现。
主动与被动联合方案的一个本质差异在于颁发的 SAML 令牌的类型。主动联合通常依靠使用“密钥所有者”(holder-of-key) 类型主体确认的 SAML 令牌,这意味着,在实际当中存在着一个证明密钥,它可以证明发出令牌进行验证的客户端是请求该令牌(也称为 ActAs 行为)的主体。被动联合方案通常涉及带有“持有者”(bearer) 类型主体确认的 SAML 令牌(也称为持有者令牌)。这种类型的令牌不包含证明密钥,有时也称为无密钥令牌。它依靠传输来确保从 STS 获得该令牌并将其传递给 RP。
认证过程如果更简单一点,我们可以用下面一个图形来展示:(代理认证)
A、 一个end user向一个web service consumer进行认证,认证的数据可能是用户输入的用户密码或证书等。
B、 web service consumer在最开始就已经跟web service provider同步了策略。这个时候,策略表示,要访问web service provider,必须要有token。于是,consumer 向sts发送了一个基于ws-trust请求,称之为RST(request security token)。Sts收到这个请求之后,就认证用户,这个认证一般是consumer传给sts的cookies。认证通过之后,就会回复一个SAML security token,这个就叫RSTR。
C、 consumer将这个SAML token 放到soap信息的头部,传送给 service provider。service provider认证这个token 是一个信任的sts发布的,于是根据相应的策略允许consumer 与 service provider之间进行交互。
更普通的用法如下:
为了实现这个,其实在WSC和WSP上都有一个代理,如下图:
在consumer与provider之间,两个OWSM代理。进行拦截过往的信息,然后分析信息,比如分析信息里面的策略,来得到相应的权限等。
认证过程如下:
A、用户通过公司的入口进入了被AM保护的程序。包含两个方面,第一,用户认证,并被AM授权。第二,程序代表用户向WSP发送请求。
B、OWSA拦截这个请求,根据WSP提供的policy,一个STS颁发的Token是需要的,于是OWSA client向STS发送请求要token。这个跟上面的一样,基于ws-trust发送RST。(这里会过滤那些没有权限的)。
C、STS认证consumer发来的用户的信息(cookies),同时还要判断这个用户是否可以被授权得到一个token。
D、若认证通过,也可以被授权获取token,那么STS就会发送一个RSTR提供一个证据表示这个用户已经被认证。
E、OWSA将token放入到soap头部,传送给WSP。
F、Wsp的OWSA拦截这个信息,提取这个信息,然后给WSP,WSP验证这个token,发现是合法的。
G、用户的访问得到准许。
整个过程我们再来梳理一遍:
上面过程主要经历4个阶段:(我们将代理的请求认定为client)
第一、client向sts请求token,一般是SAML token。
第二、STS处理RST,然后向client返回结果。
第三、client向服务发起请求。
第四、服务方面的wsp处理请求,并返回结果。
4个阶段,详细叙述如下:
第一个阶段:client向sts请求token,一般是SAML token。
1.1、 client会创建一个usertoken。
Client会根据自己的用户名和密码创建一个usertoken,用于STS对身份的鉴别。
1.2、 client创建一个RST
client根据请求的服务和服务所需要的token类型创建RST。
1.3、 client会使用签名保护RST的完整性
client会随机 一个对称密钥,用STS的公钥加密,然后传送给STS。
1.1、 client加密RST中的敏感数据
这个敏感数据主要是username和password。利用签名阶段产生的密钥可以轻易做到。
1.2、 client向STS发送RST。
第一、第二个阶段:STS处理RST,然后向client返回结果。
2.1、STS解密RST中的数据
2.2、STS验证RST数据的完整性
2.3、STS验证RST中身份凭证
根据解密出来的username,与之前保存在AD、LDAP或者数据库的数据比较,验证用户。
2.4、STS创建与身份对应的SAML Token
这是一个难点,SAML主体的确认方法,一般就是hold-of-key的确认方法。比如,client自己有一个私钥,公钥,那么,它可以在SAML中存放这样的信息:client的公钥和用私钥加密的一段信息,如果service方可以解密,那么就可以确认身份了。
问题是,并不是每一个client都有公私钥。在这种情况下如何证明自己就是SAML的拥有者呢?
因为service不信任client,但是信任STS,于是可以这样做:
STS首先生成用户的相关属性和认证信息,然后生成一个对称密钥(client和service都可以传递Entropy影响密钥的生成结果)。为了让密钥只被service收到,于是,用service的公钥加密,然后加入到SAML Token的SubjectConfirmation域中,最后STS用自己的私钥对上面的所有内容签名。保证内容是STS发送的,并且不会被更改。
那么如何将密钥安全传递给client,将由RSTR来实现。
2.5、STS发送SAML Token给client
RSTR主要包含了前面创建的SAML Token,以及为了验证client身份的那个对称密钥。将STS之前产生的密钥以明文形式包含到RSTR的RequestProofToken元素中,实现密钥向client传送。
为了不让SAML Token和RequestProofToken不被窃取,将使用client向STS发送RST时候的密钥来加密整个内容。然后发送给client。
client向STS发送的对称密钥是随机产生的。别人不知道,所以,发送给client的数据基本上是安全的。
第三个阶段: client向服务发起请求
3.1、client创建请求信息
Client首先根据请求的服务创建出相应的soap envelop.然后将RSTR中的SAML Token原封不动的放到soap envelop 的head中。
3.2、client对消息签名
Client从RequestProofToken中获取STS为client 和service创建的对称密钥。为了避免每次用同样的密钥加密签名,client将使用psha1算法从中派生出一个临时密钥,并使用它对消息进行签名。
3.3、client对消息加密
跟上面一样,根据对称密钥派生一个临时密钥,然后用它对敏感信息加密。
3.4、发送信息给service。
第四阶段: wsp处理请求,并返回结果
4.1、service解密请求消息
Service从client发来的请求消息中的head得到SAML Token,用自己的私钥解密SAML Token,获取STS办法的对称密钥,使用这个对称密钥,用client的算法计算出派生密钥。利用它,service可以将其余部分解密。
4.2、验证消息的签名
和解密类似,利用派生密钥验证签名,确保数据没有被篡改。
4.3、service验证SAML Token
Service 得到SAML Token之后,首先判断token是否在有效期范围内,其次验证token的签名,从而判断token是否是信任的STS颁发,最后根据token的主体验证方法判断token所断言的主体是否就是消息的发送方。此处采用hold-of-key。这样我们就完全可以信任这个SAML Token了。
4.4、service处理请求并返回结果(可选的)
如果有返回结果,那么service会使用与client共享的对称密钥派生一个临时密钥,加密发送给client。
如果service与client的token类型不一样,STS有这么功能,exchange。
STS的构架如下图。
这个跟上面的图基本上一致,OWSM是一个代理,在STS服务端,要跟很多打交道,比如user store进行认证,token交互的框架等等。
STS是一个token service,那么WSS就包括了很多了,用它原本的话来说就是:
Web services security encompasses multiple functional imperatives, including: authentication, authorization, confidentiality, privacy and integrity, and non-repudiation. Oracle addresses the need for web services-based security and management with a standards-compliant solution, Oracle Web Services Manager (OWSM)
上面的STS已经有过OWSM的用法了,有了OWSM,身份传播认证过程就成了这样:
在服务端和客户端都有这么一个OWSM代理进行过滤,来保证安全。
Sts在联邦认证的过程如下如:
A、app就代表user向另外一个域中的服务发起请求。一个ws_trust client拦截住这个请求,通过策略发现需要一个由STS B颁发的token。于是,先向本域中的STS A发送一个RST。
B、这个ws_trust client向STS A发送请求,希望一个token可以跟STS B进行通信。随后发送凭证给STS A。
C、A验证凭证。
D、STS A发送给client一个RSTR,表示client已经被被认证了。
E、Client向STS B发送RST,同时包含A颁发的token。
F、STS B认证A颁发的token,因为A与B是相互信任的,于是验证通过,发送一个RSTR给client,包含B的颁发的token。
G、Client将token包含在soap协议中发送给WSP。
H、WSP认证这个token,知道这个token是STS B颁发的,STS B信任STS A,于是根据策略准许client访问。
1、数据结构
2.1、token
STS支持的token有哪些呢?
发送的基于ws-trust的请求token和返回信息的格式:
有一个必填字段,Request type.如果我们是请求一个token,那么这个字段是这样:
http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue
.
Token type是可选的,它表示你可以指定返回的token的类型。比如,它可能的值:
Username Token: http://docs.oasis-open.org/wss/2004/01/oasis-200401-wsswssecurity-secext-1.0.xsd/UsernameToken
SAMLV2.0 assertion: http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0
Applies to是可选的,代表返回的token将要访问的资源。
如果,applies to和token type都有值,但是sts知道这个applies to的资源使用的token类型,那么,sts会忽略tokentype,以资源的token 类型返回给请求方。
OnBehalfOf表示,这个请求是代替第三方请求的还是自己请求的。如果是代替第三方请求,那么这里必须包含第三方的认证的token。
那么我在贴出一个rst和rstr的xml例子
RST:(一个网关请求STS,跨域)
<S:Envelope xmlns:S=”http://www.w3.org/2003/05/soap-envelope”
xmlns:wsu=”http://…/oasis-200401-wss-wssecurity-utility-1.0.xsd”
xmlns:env=”http://schemas.xmlsoap.org/soap/envelope/”
xmlns:wsse=”http://…/oasis-200401-wss-wssecurity-secext-1.0.xsd”>
<S:Header>
<wsse:Security S:mustUnderstand=”1″>
<wsse:BinarySecurityToken wsu:Id=”SecurityToken-id”
EncodingType=”http://…/oasis-200401-wss-soap-message-security-1.0#Base64Binary”
ValueType=”http://…/oasis-200401-wss-x509-token-profile-1.0#X509v3″>
Gateway X509 Certificate
</wsse:BinarySecurityToken>
<Signature xmlns=”http://www.w3.org/2000/09/xmldsig#”>
<SignedInfo>
…
</SignedInfo>
<SignatureValue>
…
</SignatureValue>
<KeyInfo>
<wsse:SecurityTokenReference>
<wsse:Reference URI=”#SecurityToken-id”
ValueType=”http://…/oasis-200401-wss-x509-token-profile-1.0#X509v3″/>
</wsse:SecurityTokenReference>
</KeyInfo>
</Signature>
…
</wsse:Security>
</S:Header>
<S:Body>
<RequestSecurityToken xmlns=”http://docs.oasis-open.org/ws-sx/ws-trust/200512″
xmlns:wsa=”http://www.w3.org/2005/08/addressing”
xmlns:pol=”http://schemas.xmlsoap.org/ws/2004/09/policy”>
<RequestType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue</RequestType>
<pol:AppliesTo>
<wsa:EndpointReference>
<wsa:Address>http://testHost/HelloService</wsa:Address>
</wsa:EndpointReference>
</pol:AppliesTo>
<OnBehalfOf>
<wsse:UsernameToken
xmlns:wsse=”http://…/oasis-200401-wss-wssecurity-secext-1.0.xsd”>
<wsse:Username>jdoe</wsse:Username>
</wsse:UsernameToken>
</OnBehalfOf>
<TokenType>http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0>
</RequestSecurityToken>
</S:Body>
</S:Envelope>
Sts回复
<S:Envelope xmlns:wsu=”http://…/oasis-200401-wss-wssecurity-utility-1.0.xsd”
xmlns:S=”http://www.w3.org/2003/05/soap-envelope”>
<S:Header>
<wsse:Security xmlns:wsse11=”http://…/oasis-wss-wssecurity-secext-1.1.xsd”
xmlns:wsse=”http://…/oasis-200401-wss-wssecurity-secext-1.0.xsd”
S:mustUnderstand=”1″>
<wsu:Timestamp>
<wsu:Created>2009-11-08T11:03:20Z</wsu:Created>
<wsu:Expires>2009-11-08T11:08:20Z</wsu:Expires>
</wsu:Timestamp>
</wsse:Security>
</S:Header>
<S:Body>
<trust:RequestSecurityTokenResponseCollection
xmlns:wst=”http://schemas.xmlsoap.org/ws/2005/02/trust”
xmlns:wsse=”http://…/oasis-200401-wss-wssecurity-secext-1.0.xsd”
xmlns:wsp=”http://schemas.xmlsoap.org/ws/2004/09/policy”
xmlns:wsa=”http://www.w3.org/2005/08/addressing”
xmlns:trust=”http://docs.oasis-open.org/ws-sx/ws-trust/200512″>
<trust:RequestSecurityTokenResponse>
<trust:TokenType>
http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0</trust:TokenType>
<trust:RequestedSecurityToken>
<saml:Assertion xmlns:saml=”urn:oasis:names:tc:SAML:2.0:assertion”
ID=”uuid-76a197ba-c2e8-4704-97a2-147db7619f2c”
IssueInstant=”2009-11-08T11:03:20Z” Version=”2.0″>
…
<saml:Subject>
<saml:NameID NameQualifier=”STS”>jdoe</saml:NameID>
<saml:SubjectConfirmation
Method=”urn:oasis:names:tc:SAML:2.0:cm:sender-vouches”/>
</saml:Subject>
…
</saml:Assertion>
</trust:RequestedSecurityToken>
<trust:RequestedAttachedReference>
<wsse:SecurityTokenReference>
<wsse:KeyIdentifier
ValueType=”http://…/wss/oasis-wss-saml-token-profile-1.1#SAMLID”>
uuid-76a197ba-c2e8-4704-97a2-147db7619f2c
</wsse:KeyIdentifier>
</wsse:SecurityTokenReference>
</trust:RequestedAttachedReference>
…
<wsp:AppliesTo>
<wsa:EndpointReference>
<wsa:Address> http://testHost/HelloService</wsa:Address>
</wsa:EndpointReference>
</wsp:AppliesTo>
<trust:Lifetime>
<wsu:Created>2009-11-08T11:03:20.344Z</wsu:Created>
<wsu:Expires>2009-11-08T11:09:20.344Z</wsu:Expires>
</trust:Lifetime>
</trust:RequestSecurityTokenResponse>
</trust:RequestSecurityTokenResponseCollection>
</S:Body>
</S:Envelope>