SAML2.0协议 - 维基百科版翻译

SAML 2.0 Specifications - http://saml.xml.org

Security Assertion Markup Language(SAML)是以XML为基础的,为在安全域间交换认证和授权数据的标准,即在 身份提供者(断言的产生者)和服务提供者(断言消费者)间进行交换。

SAML2.0在2005年3月被批准成为OASIS的标准。SAML2.0的重要方面是他的官方文档# SAMLConform, # SAMLCore, # SAMLBind, 和 # SAMLProf覆盖了协议的详细细节。如果你初次接触SAML,你应该先阅读SAML主题的介绍,然后从OASIS中阅读#SAMLOverview 文档。

来自24个企业和组织超过30人参与了SAML2.0的创建。特别值得一提的是,自由联盟把他们的 身份联盟框架(ID-FF)捐献给OASIS,ID-FF成为了SAML2.0基础规范。因此SAML2.0代表SAML1.1,自由ID-FF1.2,和Shibboleth1.3的集中。

SAML 2.0断言
SAML断言一个重要的类型被称为 “bearer”断言,它被用于帮助Web浏览器的SSO。下面是一个很短活跃周期的bearer断言,他是由身份提供者(https://idp.example.org/SAML2)发布给服务提供方的https://sp.example.com/SAML2.断言中包含<saml:AuthnStatement>和<saml:AttributeStatement>,假设该断言是服务提供方用来做访问控制决定的。
<saml:Assertion
   xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
   xmlns:xs="http://www.w3.org/2001/XMLSchema"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   ID="b07b804c-7c29-ea16-7300-4f3d6f7928ac"
   Version="2.0"
   IssueInstant="2004-12-05T09:22:05Z">
	<saml:Issuer>https://idp.example.org/SAML2</saml:Issuer>
	<ds:Signature
     xmlns:ds="http://www.w3.org/2000/09/xmldsig#">...</ds:Signature>
	<saml:Subject>
		<saml:NameID
       Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient">
       3f7b3dcf-1674-4ecd-92c8-1544f346baf8
		</saml:NameID>
		<saml:SubjectConfirmation
       Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
			<saml:SubjectConfirmationData
         InResponseTo="aaf23196-1773-2113-474a-fe114412ab72"
         Recipient="https://sp.example.com/SAML2/SSO/POST"
         NotOnOrAfter="2004-12-05T09:27:05Z"/>
		</saml:SubjectConfirmation>
	</saml:Subject>
	<saml:Conditions
     NotBefore="2004-12-05T09:17:05Z"
     NotOnOrAfter="2004-12-05T09:27:05Z">
		<saml:AudienceRestriction>
			<saml:Audience>https://sp.example.com/SAML2</saml:Audience>
		</saml:AudienceRestriction>
	</saml:Conditions>
	<saml:AuthnStatement
     AuthnInstant="2004-12-05T09:22:00Z"
     SessionIndex="b07b804c-7c29-ea16-7300-4f3d6f7928ac">
		<saml:AuthnContext>
			<saml:AuthnContextClassRef>
         urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
			</saml:AuthnContextClassRef>
		</saml:AuthnContext>
	</saml:AuthnStatement>
	<saml:AttributeStatement>
		<saml:Attribute
       xmlns:x500="urn:oasis:names:tc:SAML:2.0:profiles:attribute:X500"
       x500:Encoding="LDAP"
       NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
       Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.1"
       FriendlyName="eduPersonAffiliation">
			<saml:AttributeValue
         xsi:type="xs:string">member</saml:AttributeValue>
			<saml:AttributeValue
         xsi:type="xs:string">staff</saml:AttributeValue>
		</saml:Attribute>
	</saml:AttributeStatement>
</saml:Assertion>

注意<saml:Assertion>元素包含如下的子元素:
  • <saml:Issuer>元素,包含了身份提供者的唯一身份。
  • <ds:Signature>元素,包含了在<saml:Assertion>元素中完整保存的数字签名.
  • <saml:Subject>元素,定义了认证过的主体,但是在该实例中,因为保密的原因,主体身份被隐藏在透明的transient标识之后。
  • <saml:Conditions>元素,给出了断言被认为有效的验证条件。
  • <saml:AuthnStatement>元素,描述了在身份提供者的认证行为。
  • <saml:AttributeStatement>元素,声明了认证主体相关的多值属性。

通俗的说,断言被编码成如下信息:
在时间为"2004-12-05T09:22:05Z"时,身份提供者(https://idp.example.org/SAML2)唯一发布了关于主体(3f7b3dcf-1674-4ecd-92c8-1544f346baf8)的断言("b07b804c-7c29-ea16-7300-4f3d6f7928ac"),发送给服务提供方(https://sp.example.cin/SAML2)。
特殊说明的是,
认证声明说明如下信息:
包含在<saml:subject>中的认证过的主体元素,在时间“2004-12-05T09:22:00Z”被认证,也就是说密码通过受保护的通道被发送过来。
同样,属性声明陈述为:
在<saml:Subject>元素中的被验证的主体在一个机构中的工作人员。

SAML2.0协议
在#SAMLCore 中制定了如下协议:
  • 断言查询和请求协议(Assertion Query and Request Protocol)
  • 认证请求协议(Authentication Request Protocol)
  • 组件解决协议(Artifact Resolution Protocol)
  • 命名身份管理协议(Name Identifier Management Protocol)
  • 单点退出协议(Single Logout Protocol)
  • 命名身份映射协议(Name Identifier Mapping Protocol)

这些协议中最重要的协议,认证请求协议,在下面讲详细讨论。

认证请求协议(Authentication Request Protocol)
记得SAML 1.1 的 Web Browser SSO Profiles 是idp初始化的,也就是说,一个未经同意的<samlp:Response>元素通过浏览器从身份提供方传递到服务提供方。在SAML2.0里,流程从服务提供方开始,服务提供方发布一个详细的认证请求到身份提供方。因此,Authentication Request Protocol 是 SAML2.0的一个重要的新特性。当一个主体或者代表主体的实体,希望获得包含认证声明时,<samlp:AuthRequest>元素需要被传输到身份提供方。
<samlp:AuthnRequest
   xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
   xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
   ID="aaf23196-1773-2113-474a-fe114412ab72"
   Version="2.0"
   IssueInstant="2004-12-05T09:21:59Z"
   AssertionConsumerServiceIndex="0"
   AttributeConsumingServiceIndex="0">
	<saml:Issuer>https://sp.example.com/SAML2</saml:Issuer>
	<samlp:NameIDPolicy
     AllowCreate="true"
     Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient"/>
</samlp:AuthnRequest>

上面的<samlp:AuthnRequest>元素,暗中还请求了包含认证声明的断言,很显然是由服务提供方https://sp.example.com/SAML2 发布,随后通过浏览器传给身份提供方。身份提供方认证主体,并且发布认证响应,通过浏览器传输回服务提供方。

组件解决协议(Artifact Resolution Protocol)
SAML消息通过值 或者 值引用 从一个实体传到另一个实体。对SAML消息的引用被成为artifact。Artifact的接受者,通过直接发送<samlp:ArtifactResolve>请求到artifact的发布者 来处理引用,然后发布者响应由artifact引用的真实的消息。
例如,假设 身份提供方通过后台通道直接发送如下的<samlp:ArtifactResolve>请求到服务提供方:
<samlp:ArtifactResolve
   xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
   xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
   ID="_cce4ee769ed970b501d680f697989d14"
   Version="2.0"
   IssueInstant="2004-12-05T09:21:58Z"
   Destination="https://sp.example.com/SAML2/ArtifactResolution">
	<saml:Issuer>https://idp.example.org/SAML2</saml:Issuer>
	<ds:Signature
     xmlns:ds="http://www.w3.org/2000/09/xmldsig#">...</ds:Signature>
	<samlp:Artifact>AAQAAMh48/1oXIM+sDo7Dh2qMp1HM4IF5DaRNmDj6RdUmllwn9jJHyEgIi8=</samlp:Artifact>
</samlp:ArtifactResolve>

作为响应,服务提供方附上artifact返回SAML元素。该协议格式就是HTTP Artifact Binding基础。

SAML2.0 绑定
SAML 2.0支持的绑定有如下的绑定规范:
  • SAML SOAP 绑定(基于SOAP1.1)
  • 反SOAP绑定(PAOS);
  • HTTP重定向绑定(GET);
  • HTTP POST绑定;
  • HTTP Artifact 绑定;
  • SAML URI绑定。

对于Web浏览器的SSO,最常用的属于HTTP POST 绑定。不管是服务提供方还是身份提供方使用HTTP POST来传输协议消息,一个实体的绑定选择是和其伙伴的绑定选择是独立的。例如,服务提供方可能使用HTTP POST绑定,然而身份提供方使用的是HTTP Artifact。

HTTP POST Binding
在下属的例子中,服务提供方和身份提供方都使用HTTP POST绑定。最初,服务提供方响应 包含了一个XHTML格式文档的用户代理请求:
<form method="post" action="https://idp.example.org/SAML2/SSO/POST" ...>
   <input type="hidden" name="SAMLRequest" value="request" />
   ...
   <input type="submit" value="Submit" />
 </form>

SAMLRequest参数的值是经过64位编码的<samlp:AuthnRequest>元素,通过浏览器传输到身份提供者。身份提供方的SSO服务验证请求的有效性,并通过另一个XHTML格式的文档响应。
  <form method="post" action="https://sp.example.com/SAML2/SSO/POST" ...>
   <input type="hidden" name="SAMLResponse" value="response" />
   ...
   <input type="submit" value="Submit" />
 </form>

SAMLResponse参数的值是经过64位编码的<samlp:AuthnRequest>元素,并通过浏览器传输给服务提供方。
为了自动提交该form,下述的javascript可以出现在Xhtml页面的任意位置(假设页面里只有一个单个form元素。):
window.onload = function () { document.forms[0].submit(); }


HTTP Artifact Binding
HTTP Artifact Binding使用Artifact Resolution Protocol和HTTP之上的SOAP绑定根据引用来处理SAML消息。参考如下具体的例子。假设服务提供方发送<samlp:AuthRequest>消息到身份提供方。开始,服务提供方通过Http重定向传给一个artifact到身份提供者: https://idp.example.org/SAML2/SSO/Artifact?SAMLart=artifact。 然后,身份提供方通过后台通道直接发送<samlp:ArtifactResolve>请求到服务提供方。最后,服务提供方返回相关<samlp:AuthnRequest>消息的<samlp:ArtifactResponse>元素。
 <samlp:ArtifactResponse
   xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
   ID="_d84a49e5958803dedcff4c984c2b0d95"
   InResponseTo="_cce4ee769ed970b501d680f697989d14"
   Version="2.0"
   IssueInstant="2004-12-05T09:21:59Z">
	<ds:Signature
     xmlns:ds="http://www.w3.org/2000/09/xmldsig#">...</ds:Signature>
	<samlp:Status>
		<samlp:StatusCode
       Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
	</samlp:Status>
	<samlp:AuthnRequest
     xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
     xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
     ID="_306f8ec5b618f361c70b6ffb1480eade"
     Version="2.0"
     IssueInstant="2004-12-05T09:21:59Z"
     Destination="https://idp.example.org/SAML2/SSO/Artifact"
     ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"
     AssertionConsumerServiceURL="https://sp.example.com/SAML2/SSO/Artifact">
		<saml:Issuer>https://sp.example.com/SAML2</saml:Issuer>
		<samlp:NameIDPolicy
       AllowCreate="false"
       Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"/>
	</samlp:AuthnRequest>
</samlp:ArtifactResponse>

当然,该流程也可以转向其他流程,也就是说,身份提供方可能发布一个artifact。查看后面的“double artifact“profile例子。

Artifact 格式化
一般来说,SAML2.0 artifact 定义如下:
SAML_artifact := B64 (TypeCode EndpointIndex RemainingArtifact)
TypeCode      := Byte1Byte2
EndpointIndex := Byte1Byte2

因此SAML2.0 artifact包含3个组件:一个双字节 TypeCode,一个双字节 EndpointIndex,和一个被称为RemainArtifact的任意序列字节。这3部分信息被结合,并且经过64位编码来生成完成的artifact。
TypeCode唯一确定了artifact格式。SAML2.0预先定义了一个如下artifact,类型为0x0004.EndpointIndex是一个特殊artifact解决终点,是由artifact issuer管理的(该发行者可能是IDP,也可是SP)。RemainArtifact,由类型定义决定,是artifact的内容。
类型为0x0004的artifact格式有如下跟如定义:
TypeCode            := 0x0004
RemainingArtifact   := SourceId MessageHandle
SourceId            := 20-byte_sequence
MessageHandle       := 20-byte_sequence

因此类型为0x0004的未编码的artifact是大小为44位的字节。SourceID是一个无序字节,但是在实际应用中,SourceID是发布者实体ID经过SHA-1算法哈希的值。messageHandle
是一个随机序列,他是artifact发布者将要按照要求处理的SAML消息的引用。
例如,考虑如下类型为0x0004的artifact的哈希编码 :
00040000c878f3fd685c833eb03a3b0e1daa329d47338205e436913660e3e917549a59709fd8c91f2120222f
  详细查看会发现在该artifact的前端包含了TypeCode 为0x0004和EndpointIndex 为0x0000.剩余的20个字节是发布者的实体ID(https://idp.example.org/SAML2)和20个随机字节的SHA-1哈希值。对该44位字节进行64位编码的例子请参照上面的参照 ArtifactResolveRequest。

SAML2.0 Profiles
和SAML1.1一样,在SAML2.0中最重要的用例依然是Web浏览器的单点登录,但是SAML2.0的范围比上个版本大很多,如下:
  • SSO Profiles
  • # WebBrowser的SSO Profile;
    # Enhanced Client or Proxy (ECP) profile,增强型客户端的Profile;
    # Identity provider Discovery Profile,身份提供者发现 Profile;
    # Single Logout Profile,单点退出 Profile;
    # Name Identifier Management Profile,命名身份管理Profile。
  • Artifact Resolution Profile,Artifact处理profile.
  • Assertion Query/Request Profile ,断言查询/请求 Profile
  • Name Identifier Mapping Profile ,命名身份映射Profile
  • SAML Attribute Profiles ,SAML 属性Profile
  • # Basic Attribute Profile,基础的属性Profile
    # X.500/LDAP Attribute Profile ,X.500/LDAP属性 Profile
    # UUID Attribute Profile ,UUID 属性Profile
    # DCE PAC Attribute Profile ,DCE PAC A属性 Profile
    # XACML Attribute Profile ,XACML 属性Profile。

尽管SAML支持的profiles很多,很大,但是因为profile的每一个绑定部分都被提取出单独的绑定规范,Profiles 规范已经被简化。

Web 浏览器的单点登录Profile(WebBrowser SSO Profile)
SAML2.0指定了包含IDP,SP和使用HTTP用户代理的主体的Web浏览器的SSO Profile。SP有4种绑定方式可以选择,而IDP有3种绑定方式来选择,因此在每个场景中可以有12中可能的发布情形。下 面我们简述两种发布场景。
 
SP POST  请求;IDP POST响应
Web 浏览器中SP和IDP都是用HTTP POST 绑定方式,在SAML2.0这是一种相对简单的开发方式。
SAML2.0协议 - 维基百科版翻译
该消息流开始于SP端的对安全资源的请求,具体流程如下:
1、SP端请求目标资源
通过HTTP用户代理,主体请求在服务提供方请求一个安全资源。
https://sp.example.com/myresource
服务提供方代表目标资源进行安全检查。如果SP端存在有效的安全上下文,跳过步骤2-7.
2、XHTML方式的响应
服务提供方响应了一个包含XHTML格式的文档:
  <form method="post" action="https://idp.example.org/SAML2/SSO/POST" ...>
   <input type="hidden" name="SAMLRequest" value="request" />
   <input type="hidden" name="RelayState" value="token" />
   ...
   <input type="submit" value="Submit" />
 </form>

RelayState 标志是SP端的对状态信息保持的不透明引用。
SAMLRequest参数是如下<samlp:AuthnRequest>元素的64位编码值。
<samlp:AuthnRequest
   xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
   xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
   ID="identifier_1"
   Version="2.0"
   IssueInstant="2004-12-05T09:21:59Z"
   AssertionConsumerServiceIndex="0">
	<saml:Issuer>https://sp.example.com/SAML2</saml:Issuer>
	<samlp:NameIDPolicy
     AllowCreate="true"
     Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient"/>
</samlp:AuthnRequest>

在<samlp:AuthnRequest>元素是经过URL编码的,被插入搭配XHTML表单中之前,他首先被压缩(deflated),并且按照顺序进行64位编码。
3、请求IDP端SSO服务的请求
用户代理发布POST请求给IDP端的SSO服务。
POST /SAML2/SSO/POST HTTP/1.1
 Host: idp.example.org
 Content-Type: application/x-www-form-urlencoded
 Content-Length: nnn
 SAMLRequest=request&RelayState=token

SAMLRequest 和RelayState参数值在第2步被加入到XHTML 表单中。SSO服务处理<samlp:AuthnRequest>元素(按照顺序通过URL解码,64位解码拆分请求),并且进行安全检查。如果用户没有有效的安全上下文,身份提供方对用户进行验证。
4、XHTML表单响应
SSO服务验证请求的有效性,并响应包含如下XHTML 表单的文档
<form method="post" action="https://sp.example.com/SAML2/SSO/POST" ...>
   <input type="hidden" name="SAMLResponse" value="response" />
   <input type="hidden" name="RelayState" value="token" />
   ...
   <input type="submit" value="Submit" />
 </form>

RelayState参数在第3步骤已经进行介绍。
SAMLResponse参数是进过64位编码的如下<samlp:Response>元素:
<samlp:Response
   xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
   xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
   ID="identifier_2"
   InResponseTo="identifier_1"
   Version="2.0"
   IssueInstant="2004-12-05T09:22:05Z"
   Destination="https://sp.example.com/SAML2/SSO/POST">
	<saml:Issuer>https://idp.example.org/SAML2</saml:Issuer>
	<samlp:Status>
		<samlp:StatusCode
       Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
	</samlp:Status>
	<saml:Assertion
     xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
     ID="identifier_3"
     Version="2.0"
     IssueInstant="2004-12-05T09:22:05Z">
		<saml:Issuer>https://idp.example.org/SAML2</saml:Issuer>
		<ds:Signature
       xmlns:ds="http://www.w3.org/2000/09/xmldsig#">...</ds:Signature>
		<saml:Subject>
			<saml:NameID
         Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient">
         3f7b3dcf-1674-4ecd-92c8-1544f346baf8
			</saml:NameID>
			<saml:SubjectConfirmation
         Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
				<saml:SubjectConfirmationData
           InResponseTo="identifier_1"
           Recipient="https://sp.example.com/SAML2/SSO/POST"
           NotOnOrAfter="2004-12-05T09:27:05Z"/>
			</saml:SubjectConfirmation>
		</saml:Subject>
		<saml:Conditions
       NotBefore="2004-12-05T09:17:05Z"
       NotOnOrAfter="2004-12-05T09:27:05Z">
			<saml:AudienceRestriction>
				<saml:Audience>https://sp.example.com/SAML2</saml:Audience>
			</saml:AudienceRestriction>
		</saml:Conditions>
		<saml:AuthnStatement
       AuthnInstant="2004-12-05T09:22:00Z"
       SessionIndex="identifier_3">
			<saml:AuthnContext>
				<saml:AuthnContextClassRef>
           urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
				</saml:AuthnContextClassRef>
			</saml:AuthnContext>
		</saml:AuthnStatement>
	</saml:Assertion>
</samlp:Response>

5、请求SP端的断言消费服务
用户代理发布POST请求到SP端的断言消费服务:
POST /SAML2/SSO/POST HTTP/1.1
 Host: sp.example.com
 Content-Type: application/x-www-form-urlencoded
 Content-Length: nnn
 SAMLResponse=response&RelayState=token

其中SAMLResponse和RelayState参数在第4步已经被加载到XHTML表单。
6、重定向到目标资源
断言消费服务处理响应,在SP端创建安全上下文,并通过用户代理重定向到目标资源
7、再次请求SP边的目标资源
用户代理再次请求SP段的目标资源:
https://sp.example.com/myresource
8、响应请求的资源
因为安全上下文已经建立,服务提供方返回资源到用户代理。

SP重定向Artifact,IDP重定向Artifact(Artifact Resolution Profile)
在Web浏览器SSO Profile 中SP和IDP都使用HTTP Artifact绑定,是在SAML2.0中的一个复杂的实现。两者artifacts分别通过HTTP GET方式传递给各自的端点。
SAML2.0协议 - 维基百科版翻译
消息流开始于SP端的安全资源请求。
1、请求SP端的目标资源
通过HTTP 用户代理,主体请求服务提供方的目标资源。
https://sp.example.com/myresource
服务提供方代表目标资源进行安全检查。如果在SP端存在有效的安全资源上下文,跳过2-11.
2、重定向到IDP端的单点登录服务
服务提供方通过用户代理转向到身份提供方的单点登录服务。RelayState参数和SAMLart参数同URL一同传给IDP;
3、请求IDP端的单点登录服务
用户代理请求idp端的单点登录服务。
https://idp.example.org/SAML2/SSO/Artifact?SAMLart=artifact_1&RelayState=token
其中token是服务提供方状态信息的不透明引用,artifact_1是一个SAML artifact,这两个信息是在第2步产生的。
4、请求SP端的Artifact Resolution Service
通过发送绑定到SAML SOAP消息的<samlp: ArtifactResolve>元素到服务提供方的artifact resolution 服务,SSO服务会再次引用artifact。
<samlp:ArtifactResolve
   xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
   xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
   ID="identifier_1"
   Version="2.0"
   IssueInstant="2004-12-05T09:21:58Z"
   Destination="https://sp.example.com/SAML2/ArtifactResolution">
	<saml:Issuer>https://idp.example.org/SAML2</saml:Issuer>
	<ds:Signature
     xmlns:ds="http://www.w3.org/2000/09/xmldsig#">...</ds:Signature>
	<samlp:Artifact>artifact_1</samlp:Artifact>
</samlp:ArtifactResolve>

其中<samlp:Artifact>元素中的值是在第3步产生的SAML artifact。
5、响应SAML AuthnRequest
服务提供方的artifact Resolution服务返回一个包含<samlp:AuthnRequest> 的<samlp:ArtifactResponse>元素,该元素绑定到SAML SOAP消息,然后发送到身份提供方的SSO服务。
<samlp:ArtifactResponse
   xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
   ID="identifier_2"
   InResponseTo="identifier_1"
   Version="2.0"
   IssueInstant="2004-12-05T09:21:59Z">
	<ds:Signature
     xmlns:ds="http://www.w3.org/2000/09/xmldsig#">...</ds:Signature>
	<samlp:Status>
		<samlp:StatusCode
       Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
	</samlp:Status>
	<samlp:AuthnRequest
     xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
     xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
     ID="identifier_3"
     Version="2.0"
     IssueInstant="2004-12-05T09:21:59Z"
     Destination="https://idp.example.org/SAML2/SSO/Artifact"
     ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"
     AssertionConsumerServiceURL="https://sp.example.com/SAML2/SSO/Artifact">
		<saml:Issuer>https://sp.example.com/SAML2</saml:Issuer>
		<samlp:NameIDPolicy
       AllowCreate="false"
       Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"/>
	</samlp:AuthnRequest>
</samlp:ArtifactResponse>

SSO服务处理<samlp:AuthnRequest>元素,并进行安全检查。如果用户没有一个有效地安全上下文,身份提供方对用户身份进行验证。
6、重定向到断言消费服务
IDP端的SSO服务通过用户代理转向到SP端的断言消费服务。先前的RelayState参数和新的SAMLart参数和URL一并转向到请求端。
7、请求SP端的断言消费服务
用户代理请求在服务提供方的断言消费服务。
https://sp.example.com/SAML2/SSO/Artifact?SAMLart=artifact_2&RelayState=token
其中Token是第3步骤产生的,artifact_2是在步骤6中产生。
8、请求IDP端的Artifact Resolution Service
通过发送绑定到SAML SOAP消息 中的<samlp:ArtifactResolve>元素到身份提供方的artifact resolution服务,断言消费服务会再次引用该artifact。
<samlp:ArtifactResolve
   xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
   xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
   ID="identifier_4"
   Version="2.0"
   IssueInstant="2004-12-05T09:22:04Z"
   Destination="https://idp.example.org/SAML2/ArtifactResolution">
	<saml:Issuer>https://sp.example.com/SAML2</saml:Issuer>
	<ds:Signature
     xmlns:ds="http://www.w3.org/2000/09/xmldsig#">...</ds:Signature>
	<samlp:Artifact>artifact_2</samlp:Artifact>
</samlp:ArtifactResolve>

其中<samlp:Artifact>元素的值是在步骤7中传递过来的。
9、响应断言
IDP端的 Artifact  resolution服务返回包含了<samlp:Response>的<samlp:ArtifactResponse>元素,然后绑定到SAML SOAP消息发送到服务提供方的断言消费服务。
<samlp:ArtifactResponse
   xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
   ID="identifier_5"
   InResponseTo="identifier_4"
   Version="2.0"
   IssueInstant="2004-12-05T09:22:05Z">
	<ds:Signature
     xmlns:ds="http://www.w3.org/2000/09/xmldsig#">...</ds:Signature>
	<samlp:Status>
		<samlp:StatusCode
       Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
	</samlp:Status>
	<samlp:Response
     xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
     xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
     ID="identifier_6"
     InResponseTo="identifier_3"
     Version="2.0"
     IssueInstant="2004-12-05T09:22:05Z"
     Destination="https://sp.example.com/SAML2/SSO/Artifact">
		<saml:Issuer>https://idp.example.org/SAML2</saml:Issuer>
		<ds:Signature
       xmlns:ds="http://www.w3.org/2000/09/xmldsig#">...</ds:Signature>
		<samlp:Status>
			<samlp:StatusCode
         Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
		</samlp:Status>
		<saml:Assertion
       xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
       ID="identifier_7"
       Version="2.0"
       IssueInstant="2004-12-05T09:22:05Z">
			<saml:Issuer>https://idp.example.org/SAML2</saml:Issuer>
			<saml:Subject>
				<saml:NameID
           Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">
           [email protected]
				</saml:NameID>
				<saml:SubjectConfirmation
           Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
					<saml:SubjectConfirmationData
             InResponseTo="identifier_3"
             Recipient="https://sp.example.com/SAML2/SSO/Artifact"
             NotOnOrAfter="2004-12-05T09:27:05Z"/>
				</saml:SubjectConfirmation>
			</saml:Subject>
			<saml:Conditions
         NotBefore="2004-12-05T09:17:05Z"
         NotOnOrAfter="2004-12-05T09:27:05Z">
				<saml:AudienceRestriction>
					<saml:Audience>https://sp.example.com/SAML2</saml:Audience>
				</saml:AudienceRestriction>
			</saml:Conditions>
			<saml:AuthnStatement
         AuthnInstant="2004-12-05T09:22:00Z"
         SessionIndex="identifier_7">
				<saml:AuthnContext>
					<saml:AuthnContextClassRef>
             urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
					</saml:AuthnContextClassRef>
				</saml:AuthnContext>
			</saml:AuthnStatement>
		</saml:Assertion>
	</samlp:Response>
</samlp:ArtifactResponse>

10、重定向到目标资源
断言消费服务处理响应,并在服务提供方创建安全的上下文,并重定向到目标资源到用户代理。
11、再次请求SP的安全资源
用户代理再次请求服务提供方的目标资源:
https://sp.example.com/myresource
12、相应目标资源请求
因为安全资源已经存在,服务提供方返回资源到用户代理。

身份提供方发现 Profile(Identity Provider Discovery Profile)
SAML 2.0身份提供者发现 profile 介绍了如下概念:
  • Common Domain ,公共域
  • Common Domain Cookie ,公共域cookie
  • Common Domain Cookie Writing Service ,公共域写服务
  • Common Domain Cookie Reading Service ,公共域读服务

举一个例子,假设NWA(nwa.com)和KLM(klm.com)属于虚拟组织SkyTeam Clobal Alliance(skyteam.com)。在这个例子中,skyteam.com称为公共域。NWA和KLM在该公共域中拥有自己的代表域nwa.skyteam.com和klm.skyteam.com.
公共域cookie是一个面向整个公共域的安全浏览器cookie。对于每一个浏览器用户来说,cookie存储了最近访问IdP的历史列表。Cookie的名值指定了IDP发现Profile.
在成功完成认证行为后,Idp请求公共域写服务。该服务会增加idp的唯一标识到公共域cookie中。当SP接受到一个对受保护资源的未认证的请求时,会向公共域读服务请求发现浏览器用户最近使用最多的IDP。

断言 查询/请求 Profile(Assertion Query/Request Profile)
断言查询/请求Profile是个常见的profile,它使用如下SAML2.0元素提供了大量被称为queries的类型:
  • <samlp:AssertionIDRequest>元素,被用来请求赋予唯一ID的断言。
  • <saml:SubjectQuery>元素,是一个抽象的扩展点,允许定义新的面向对象的SAML查询。
  • <samlp:AuthnQuery>元素,用来向属性授权请求给定的主题相关属性
  • <samlp:AuthzDecisionQuery>元素,用来向受信任的第三方请求授权决定。

SAML SOAP绑定通常用在查询使用中。

SAML属性查询(SAML Attribute Query)
属性可能是SAML查询中最重要的类型。通常请求方代表主体向身份提供者查询属性。如下是主题直接发布查询的例子:
<samlp:AttributeQuery
   xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
   xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
   ID="aaf23196-1773-2113-474a-fe114412ab72"
   Version="2.0"
   IssueInstant="2006-07-17T20:31:40Z">
	<saml:Issuer
     Format="urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName">
     C=US, O=NCSA-TEST, OU=User, [email protected]
	</saml:Issuer>
	<saml:Subject>
		<saml:NameID
       Format="urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName">
       C=US, O=NCSA-TEST, OU=User, [email protected]
		</saml:NameID>
	</saml:Subject>
	<saml:Attribute
     NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
     Name="urn:oid:2.5.4.42"
     FriendlyName="givenName">
	</saml:Attribute>
	<saml:Attribute
     NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
     Name="urn:oid:1.3.6.1.4.1.1466.115.121.1.26"
     FriendlyName="mail">
	</saml:Attribute>
</samlp:AttributeQuery>

在该实例中,Issuer为Subject,有时被称为属性自查询。身份提供方会返回如下的断言,被封装到<samlp:Response>中(在下面示例中未展现):
<saml:Assertion
   xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
   xmlns:xs="http://www.w3.org/2001/XMLSchema"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
   ID="_33776a319493ad607b7ab3e689482e45"
   Version="2.0"
   IssueInstant="2006-07-17T20:31:41Z">
	<saml:Issuer>https://idp.example.org/SAML2</saml:Issuer>
	<ds:Signature>...</ds:Signature>
	<saml:Subject>
		<saml:NameID
       Format="urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName">
       C=US, O=NCSA-TEST, OU=User, [email protected]
		</saml:NameID>
		<saml:SubjectConfirmation
       Method="urn:oasis:names:tc:SAML:2.0:cm:holder-of-key">
			<saml:SubjectConfirmationData>
				<ds:KeyInfo>
					<ds:X509Data>
						<ds:X509Certificate>
 MIICiDCCAXACCQDE+9eiWrm62jANBgkqhkiG9w0BAQQFADBFMQswCQYDVQQGEwJV
 UzESMBAGA1UEChMJTkNTQS1URVNUMQ0wCwYDVQQLEwRVc2VyMRMwEQYDVQQDEwpT
 UC1TZXJ2aWNlMB4XDTA2MDcxNzIwMjE0MVoXDTA2MDcxODIwMjE0MVowSzELMAkG
 A1UEBhMCVVMxEjAQBgNVBAoTCU5DU0EtVEVTVDENMAsGA1UECxMEVXNlcjEZMBcG
 A1UEAwwQdHJzY2F2b0B1aXVjLmVkdTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC
 gYEAv9QMe4lRl3XbWPcflbCjGK9gty6zBJmp+tsaJINM0VaBaZ3t+tSXknelYife
 nCc2O3yaX76aq53QMXy+5wKQYe8Rzdw28Nv3a73wfjXJXoUhGkvERcscs9EfIWcC
 g2bHOg8uSh+Fbv3lHih4lBJ5MCS2buJfsR7dlr/xsadU2RcCAwEAATANBgkqhkiG
 9w0BAQQFAAOCAQEAdyIcMTob7TVkelfJ7+I1j0LO24UlKvbLzd2OPvcFTCv6fVHx
 Ejk0QxaZXJhreZ6+rIdiMXrEzlRdJEsNMxtDW8++sVp6avoB5EX1y3ez+CEAIL4g
 cjvKZUR4dMryWshWIBHKFFul+r7urUgvWI12KbMeE9KP+kiiiiTskLcKgFzngw1J
 selmHhTcTCrcDocn5yO2+d3dog52vSOtVFDBsBuvDixO2hv679JR6Hlqjtk4GExp
 E9iVI0wdPE038uQIJJTXlhsMMLvUGVh/c0ReJBn92Vj4dI/yy6PtY/8ncYLYNkjg
 oVN0J/ymOktn9lTlFyTiuY4OuJsZRO1+zWLy9g==
						</ds:X509Certificate>
					</ds:X509Data>
				</ds:KeyInfo>
			</saml:SubjectConfirmationData>
		</saml:SubjectConfirmation>
	</saml:Subject>
	<saml:Conditions
     NotBefore="2006-07-17T20:31:41Z"
     NotOnOrAfter="2006-07-18T20:21:41Z">
	</saml:Conditions>
	<saml:AuthnStatement
     AuthnInstant="2006-07-17T20:31:41Z">
		<saml:AuthnContext>
			<saml:AuthnContextClassRef>
           urn:oasis:names:tc:SAML:2.0:ac:classes:TLSClient
			</saml:AuthnContextClassRef>
		</saml:AuthnContext>
	</saml:AuthnStatement>
	<saml:AttributeStatement>
		<saml:Attribute
       xmlns:x500="urn:oasis:names:tc:SAML:2.0:profiles:attribute:X500"
       x500:Encoding="LDAP"
       NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
       Name="urn:oid:2.5.4.42"
       FriendlyName="givenName">
			<saml:AttributeValue
         xsi:type="xs:string">Tom</saml:AttributeValue>
		</saml:Attribute>
		<saml:Attribute
       xmlns:x500="urn:oasis:names:tc:SAML:2.0:profiles:attribute:X500"
       x500:Encoding="LDAP"
       NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
       Name="urn:oid:1.3.6.1.4.1.1466.115.121.1.26"
       FriendlyName="mail">
			<saml:AttributeValue
         xsi:type="xs:string">[email protected]</saml:AttributeValue>
		</saml:Attribute>
	</saml:AttributeStatement>
</saml:Assertion>

和前面展示的BearAssertion对照,该断言相比主体用来认证身份提供者的X.509证书的生命周期的时间更长。然而,因为断言是签名的,用户可以把断言发送给依赖联盟,并且用户可以证明证书相应私钥的所有者,依赖联盟会确认断言是可信的。

SAML 2.0 Metadata
毫不夸张的说,metadata是用来使SAML工作,或者说工作良好的关键。来看一下metadata工作的例子:
  • 通过浏览器,身份提供方接受到服务提供方发送的<samlp:AuthnRequest>元素。身份提供方是如何相信发送的服务提供方是合法的,而不是恶意服务提供方用来窃取用户的私有信息呢。答案是Metadata!在发送认证响应之前,身份提供方会向metadata中查询受信任的服务提供方。
  • 在以前的场景中,身份提供者是如何知道认证响应转向的地址呢?答案是Metadata!身份提供方查询会查询metadata中已经安排好的服务提供方的终端。
  • 服务提供方是如何知道认证响应来自受信任的身份提供方。答案是metadata!服务提供方用公钥判断断言的有效性。数据也来自于metadata。
  • 服务提供方是怎么知道到受信任的身份提供方的那个位置来处理artifact呢?答案是metadata。服务提供从metadata中查找先前安排好的身份提供方artifact出阿里服务的终端。

还有很多类似这样的例子。元数据在身份提供方和服务提供方间保持着安全事务(bootstraps)。在metadata之前,受信任信息根据服务的自身定义被编码。现在受信任信息很容易通过标准的metadata来共享。SAML2.0提供了定义良好,可互操作的metadata格式,通过这个格式可以使实体保持受信任过程的处理平衡(that entities can leverage to bootstrap the trust process)。

Identity Provider Metadata
身份提供方发布了自身的数据到<md:EntityDescriptor>元素:
<md:EntityDescriptor 
   xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
   xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
   xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
   entityID="https://idp.example.org/SAML2">
	<!-- insert ds:Signature element -->
	<!-- insert md:IDPSSODescriptor element (below) -->
	<!-- insert md:AttributeAuthorityDescriptor element (not shown) -->
	<md:Organization>
		<md:OrganizationName xml:lang="en">
       SAML Identity Provider 
		</md:OrganizationName>
		<md:OrganizationDisplayName xml:lang="en">
       SAML Identity Provider @ Some Location
		</md:OrganizationDisplayName>
		<md:OrganizationURL xml:lang="en">
       http://www.idp.example.org/
		</md:OrganizationURL>
	</md:Organization>
	<md:ContactPerson contactType="technical">
		<md:SurName>SAML IdP Support</md:SurName>
		<md:EmailAddress>mailto:[email protected]</md:EmailAddress>
	</md:ContactPerson>
</md:EntityDescriptor>

entityID属性是身份提供方的唯一标识。注意数字签名的细节(<ds:Signature>元素)在本例中已被忽略。
身份提供方管理sso服务和属性授权,每一个属性都拥有自己的描述。我们在下面描述了SSO服务metadata为<md:AttributeAuthorityDescriptor>元素也没有在实例中显示。

SSO Service metadata
身份提供方SSO 服务在<md:IDPSSODescriptor>元素中描述:
<md:IDPSSODescriptor
   protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
	<md:KeyDescriptor use="signing">
		<ds:KeyInfo>
			<ds:KeyName>IdP SSO Key</ds:KeyName>
		</ds:KeyInfo>
	</md:KeyDescriptor>
	<md:ArtifactResolutionService isDefault="true" index="0"
     Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"
     Location="https://idp.example.org/SAML2/ArtifactResolution"/>
	<md:NameIDFormat>
     urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress
	</md:NameIDFormat>
	<md:NameIDFormat>
     urn:oasis:names:tc:SAML:2.0:nameid-format:transient
	</md:NameIDFormat>
	<md:SingleSignOnService
     Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
     Location="https://idp.example.org/SAML2/SSO/POST"/>
	<md:SingleSignOnService
     Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"
     Location="https://idp.example.org/SAML2/Artifact"/>
	<saml:Attribute
     NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
     Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.1"
     FriendlyName="eduPersonAffiliation">
		<saml:AttributeValue>member</saml:AttributeValue>
		<saml:AttributeValue>student</saml:AttributeValue>
		<saml:AttributeValue>faculty</saml:AttributeValue>
		<saml:AttributeValue>employee</saml:AttributeValue>
		<saml:AttributeValue>staff</saml:AttributeValue>
	</saml:Attribute>
</md:IDPSSODescriptor>

先前的元数据元素在身份提供方中描述了SSO 服务。注意以下元素的细节描述:
  • key信息被简单概括;
  • <md:ArtifactResolutionService>元素的绑定属性指明SAML SOAP绑定应该使用artifact处理;
  • <md:ArtifactResolutionService>元素的Location 属性,被用在步骤8中的“double artifact” profile。
  • <md:ArtifactResolutionService>元素的index属性的值被用做 SAML 类型为0x0004的artifact 的EndpointIndex。
  • <md:NameIDFormat>元素表明SSO服务支持什么名称标识格式。
  • <md:SingleSignOnService>元素的Binding属性是由SAML2.0绑定规范定的标准URIs。
  • 支持HTTP POST绑定的<md:SingleSignOnService>元素的Location属性被用在 “double POST”profile的步骤2.
  • 支持HTTP artifact绑定的<md:SingleSignOnService>元素的Location属性被用在“double artifact”Profile的步骤2.
  • <saml:Attribute>元素描述了身份提供方要声明的属性。<saml:AttributeValue>元素列举出属性可用用到的可能值。

Service Provider metadata
服务提供方同样发布数据到<md:EntityDescriptor>元素。
<md:EntityDescriptor
   xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
   xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
   xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
   entityID="https://sp.example.com/SAML2">
	<!-- insert ds:Signature element -->
	<!-- insert md:SPSSODescriptor element (see below) -->
	<md:Organization>
		<md:OrganizationName xml:lang="en">
       SAML Service Provider 
		</md:OrganizationName>
		<md:OrganizationDisplayName xml:lang="en">
       SAML Service Provider @ Some Location
		</md:OrganizationDisplayName>
		<md:OrganizationURL xml:lang="en">
       http://www.sp.example.com/
		</md:OrganizationURL>
	</md:Organization>
	<md:ContactPerson contactType="technical">
		<md:SurName>SAML SP Support</md:SurName>
		<md:EmailAddress>mailto:[email protected]</md:EmailAddress>
	</md:ContactPerson>
</md:EntityDescriptor>

由服务提供者管理的主要组件是断言消费服务,下面将对断言消费服务进行讨论。
Assertion Consumer Service Metadata
断言消费服务由<md:SPSSODescriptor>元素来代表:
<md:SPSSODescriptor
   protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
	<md:KeyDescriptor use="signing">
		<ds:KeyInfo>
			<ds:KeyName>SP SSO Key</ds:KeyName>
		</ds:KeyInfo>
	</md:KeyDescriptor>
	<md:ArtifactResolutionService isDefault="true" index="0"
     Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"
     Location="https://sp.example.com/SAML2/ArtifactResolution"/>
	<md:NameIDFormat>
     urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress
	</md:NameIDFormat>
	<md:NameIDFormat>
     urn:oasis:names:tc:SAML:2.0:nameid-format:transient
	</md:NameIDFormat>
	<md:AssertionConsumerService isDefault="true" index="0"
     Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
     Location="https://sp.example.com/SAML2/SSO/POST"/>
	<md:AssertionConsumerService index="1"
     Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"
     Location="https://sp.example.com/SAML2/Artifact"/>
	<md:AttributeConsumingService isDefault="true" index="0">
		<md:ServiceName xml:lang="en">
       Service Provider Portal
		</md:ServiceName>
		<md:RequestedAttribute
       NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
       Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.1"
       FriendlyName="eduPersonAffiliation">
		</md:RequestedAttribute>
	</md:AttributeConsumingService>
</md:SPSSODescriptor>

注意下面详细描述了<md:SPSSODescriptor>metadata的元素:
  • <md:AssertionConsumerService>元素中index属性被用作<samlp:AuthnRequest>元素中AssertionConsumerServiceIndex属性的值。
  • 支持HTTP POST 绑定(index=”0”)的<md:AssertionConsumerService>元素中的Location属性被用在“double POST”Profile中的第4步;
  • 支持HTTP Artifact绑定(index=”1”)的<md:AssertionConsumerService>元素中的Location属性被用在“double artifact”Profile中的第6步;
  • <md:AssertionConsumerService>元素是被身份提供方用来明确表述<saml:AttributeStatement>元素,<saml:AttributeStatement>是在Web浏览器SSO中被推到服务提供方的。
  • <md:AttributeConsumerService>元素中的index属性是用作<samlp:AuthnRequest>元素中AssertionConsumerServiceIndex属性的值。


参考资料
【SAMLOverview】
【SAMLConform】
【SAMLCore】
【SAMLBind】
【SAMLProf】
【SAMLMeta】
【SAMLAuthnCtx】
【SAMLSecurity】
【SAMLGlossary】

转自:
SAML 2.0
SAML2.0协议翻译.doc

你可能感兴趣的:(翻译)