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这是一种相对简单的开发方式。
该消息流开始于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方式传递给各自的端点。
消息流开始于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