SAML

转载自:https://www.cnblogs.com/shuidao/p/3463947.html

提到SAML (Security Assertion Markup Language), 很多人都会联想到单点登录SSO。那么Saml到底是什么,它跟sso到底有什么联系?这里给大家分享一下我在读完了saml差不多全部规范之后的一些心得。希望给saml入门者一些帮助。 我并不想详细介绍每个xml节点怎么写。大家可以参考标准规范。 看了这篇随笔,相信如果万一哪天你要做saml, 你也不会害怕了。 

Saml是什么

首先,saml是一种xml格式的语言。 翻译过来大概叫 安全断言(标记)语言。  这里有两个点: 第一是“安全”, 第二是“断言(assertion)”。  用人话翻译saml就是 用安全的方式表达断言一种语言。 

先看它的核心概念“断言”。  断言是什么?  就是做出判断的语言。比如一句话: 小明是超级管理员。 这就是一个断言。再来一个例子:小红没有权限读取根目录。这也是一个断言。  这种“做出判断的语句”我们在很多场合都需要用到。  比如你在网上尝试登陆一个服务的时候, 这个服务需要知道你是不是合法的用户。 这个时候如果你能提供一个“安全,可靠,可信任”的断言:“小明有权登陆XX服务”, 那么这个服务就知道你合法了, 于是就能为你提供服务了。  这个例子比较抽象,但基本上能表达断言在实际用例中的作用了。 实际上saml的大部分用例就在于证明你是谁,你拥有什么权限等等了。 saml中大部分主要内容也都是类似于:你是谁, 你有什么。。等等这些简单的语句。 详细内容后面会介绍。

接下来第二个概念就是“安全”了。  你能提供一个断言, 别人能不能假冒你提供一个断言从而骗取服务端的信任呢? 另外服务端为什么会信任你给的断言呢? 这就涉及到安全的问题了。为了防止断言被假冒,篡改。saml中加入了安全措施。 当然现今能抵御假冒,篡改,重放攻击的利器就是公钥-私钥系统了。  通过给断言加上签名和加密,再结合数字证书系统就确保了saml不受攻击。

 

在很多sso的场合中, 都支持saml登陆。 这就是saml最多的一个应用场景。  作用相当于大家熟知的OpenID,和Oauth等等。

 

好了,说完了大体的概念,就来程序员最喜欢的硬菜了。  

 

从技术的角度看saml。

saml迄今为止有两个广泛应用的标准, Saml 1.1 和Saml 2.0

为了尝鲜,大家先看两个saml的例子, 看个样子即可,不用阅读内容,给你1分钟, 看完赶紧回来接着看这里哦:

http://en.wikipedia.org/wiki/SAML_1.1

http://en.wikipedia.org/wiki/SAML_2.0

 

恩,很好, 你已经知道saml大概长什么样了。   saml1.1和saml2.0 是同一个标准的两个版本, 他们在逻辑概念或者对象结构上大致相当, 只是在一些细节上有所差异。 这两个版本不兼容。 另外1.1比2.0要简单许多。  所以下面在讲逻辑结构的时候一般不区分这两个版本,除非特别说明的地方。

我猜你一定喜欢下面这种图:

这张图取自:  https://www.oasis-open.org/committees/download.php/11511/sstc-saml-tech-overview-2.0-draft-03.pdf

这是saml2.0的一个极其简单的应用场景.  如果你不嫌烦的话,我来解释一下这个图:

图上共有三个角色, 1,SP, 服务提供者。 2, Idp,认证用户并生成断言。 3,就是用户你了, client。

首先, 你(client)是idp的注册用户, 它有你的用户名和密码,它可以认证你就是你。 其次, SP和Idp两者会被各自的域管理员设置为相互信任对方。并且双方都持有对方的公钥。这是配置好的。第三,有一天,你需要访问sp提供的某个服务,但是sp并不认识你,也没有你的用户名和密码因此不能认证你。 于是就发生了上图所示的8个步骤:

1. 你去访问sp的某个受保护资源,比如浏览器打开: http://www.apc.com/resource1.aspx.

2. sp发现你是新来的,没有认证信息。当然不能给你这个页面内容了。 他就会生成一个 saml的认证请求数据包(当然是saml格式的)。把这个请求放在一个html的form的一个隐藏的域中,把这个html form返回给你。 这个form后面有一句javascript自动提交这个form。 二而form的action地址就是 提前配置好的 idp上的一个地址。 

saml认证请求的数据包可能是这个样子的:

==========

<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:59"  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>

==========

而返回的html from内容大概设这个样子的:它包含了上面的数据包作为其中一个hidden的值。

=============================

<form method="post" action="https://idp.example.org/SAML2/SSO/POST" ...> <input type="hidden" name="SAMLRequest" value="<samlp:AuthnRequest>.......... </samlp:authnreques>" /> ... other input parameter.... <input type="submit" value="Submit" />

</form>

<javascript>
document.form[0].submit();// 后面紧跟一句类似这样的提交代码.
</javascript>

=============================

这些代码一部分是复制过来的, 有些是我现写的, 大家领会意思即可,不要在意那些细节。

 

3. 上面的form会被javascript自动提交到idp的某个地址。

4. idp也需要认证你, 于是返回给你一个认证的页面, 可能使用用户名密码认证,也可以使用ntlm认证等等一切可以认证你的方式。 因为idp保存有你的用户名和密码。

5. 同上一步,也是认证你的一个过程。

6. idp在认证你之后。觉得你合法, 于是就为你生成一些断言, 证明你是谁,你有什么权限等等。 并用自己的私钥签名。 然后包装成一个response格式,放在form里返回给你。

断言的格式大概如下:

=============

<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:05"> <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:Subject> <saml:Conditions ......... </saml:Conditions> <saml:AuthnStatement  AuthnInstant="2004-12-05T09:22:00"  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>

=============

其中authnstatement认证语句表示你认证成功了。subject表示你是谁。而attributestatement表示你有哪些属性。 还有一个授权语句上面例子中没有。

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:05"  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:05"> <saml:Issuer>https://idp.example.org/SAML2</saml:Issuer> <!-- a POSTed assertion MUST be signed --> .................... </saml:Assertion> </samlp:Response>

============================

正如上面第2步一样,它也会把response包装在一个form里面返回给你,并自动提交给 sp的某个地址。

===========

 <form method="post" action="https://sp.example.com/SAML2/SSO/POST" ...> <input type="hidden" name="SAMLResponse" value="<samlp:Response>.........</samlp:respons>" /> <input type="hidden" name="RelayState" value="''token''" /> ... <input type="submit" value="Submit" /> </form>
<javascript>
document.form[0].submit();// 后面紧跟一句类似这样的提交代码.
</javascript>
 

===========

 

7. 于是就到了第7步, 这个form被javascript自动提交到sp了。 

8. sp读到form提交上来的 断言。 并通过idp的公钥验证了断言的签名。 于是信任了断言。 知道你是idp的合法用户了。 所以就最终给你返回了你最初请求的页面了。  http://www.apc.com/resource1.aspx.

 

好了一个最简单的saml用例就讲完了。 你可以看到其中几乎所有的步骤都可以自动完成,用户在第一步访问资源之后,就看到浏览器再自动跳转,自己不需要操作什么,几秒钟过后,资源就访问成功了。

 

到这里, 相信saml在你心目中的形象一定跟家立体了。  如果你还有兴趣就继续往下看吧.

上面是“远观”, 下面我们走近。

先看saml标准的结构:

 

此图出自: https://www.oasis-open.org/committees/download.php/11511/sstc-saml-tech-overview-2.0-draft-03.pdf  

saml标准从内到外 可以分为上图的4个层次:

1. Assertion。 断言。 规定了断言的xml结构, 例如:

==============

<saml:Assertion>

..............

</saml:Assertion?

==============

它规定了,这个assertion节点到底该怎么写, 其实就是这个节点的schema。 按照这个规定写出来的assertion别人才能认识。

2. Protocols。协议。它规定了如何请求(samlrequest)和回复(samlresponse )saml消息,其中当然包含assertion的消息。比如:

===============

<samlp:AuthnRequest>

............

</samlp:AuthnRequest>

 

还有:

 <samlp:Response> 

..............

</samlp:Response>

 

===============

它规定了怎么发送这些请求消息,和回复消息的结构。 这样sp,idp之间才能通信。

 

3. 绑定。  上面两点都是规定了静态结构。 具体这些消息怎么发送呢。 就是用什么协议来承载这些smal消息呢。就是绑定出马了。 最常用的就是http或者soap消息。  把上面的saml消息通过http或者soap消息来传输。 这样sp和idp就能通信了。  saml1.1只支持 http的soap绑定。 而saml2.0支持更多的绑定。 有兴趣自己阅读标准。   这里需要强调的是, 你可能已经想到了,那就是这个绑定其实不重要。 只要saml消息本身是完整的可靠的,下层用什么协议传输不重要。  对。 saml标准规定的绑定只是一种标准实现。  saml的消息可以绑定到任何协议上, 只要sp和idp实现协商好就行了。  这里面应用最广泛的恐怕要算saml的wss绑定了。 用在微软的一系列产品里面。 包括sharepoint online的登陆授权, windows azure登陆,以及windows store的登陆授权等等。  微软自己在ws-trust和ws-secure协议上传输了saml消息。  这恐怕是saml标准以外用的最多的绑定了。

4. Profile, 这个单词我实在不知道翻译成啥好,所以就写原文把。 我个人喜欢把它叫做一套配置,或者叫解决方案。 它规定了某些场景下一整套saml认证的细节和步骤。 比如, 它规定了比较著名的SSO方案。 就是如何用saml实现sso的一整套配置和详细步骤。  概念就是这样。  同上, 上面的绑定都不确定,所以这个profile就更自由了。 你可以使用任何自己定义的profile,只要你们自己协商好就行了。

 

恩好吧, 先到这吧。大体结构已经出来了。 后续我可能会再分享一下有趣或者有坑的地方。 欢迎大家访问我的个人独立博客交流学习: http://byNeil.com

附上saml协议标准地址:

https://www.oasis-open.org/committees/download.php/3406/oasis-sstc-saml-core-1.1.pdf

http://docs.oasis-open.org/security/saml/v2.0/saml-core-2.0-os.pdf

转载于:https://www.cnblogs.com/maxigang/p/9051257.html

<think>好的,用户之前让我介绍了OAuth 2.0,现在又要求介绍SAML协议。我需要先确定用户的需求。可能用户是在学习身份验证和授权相关的协议,或者是需要为项目选择合适的安全方案。用户可能对OAuth和SAML的区别不太清楚,所以需要对比两者的不同,或者用户想深入了解SAML的具体细节。 首先,我应该回忆SAML的基本概念,核心组成部分,以及它的应用场景。SAML是基于XML的标准,主要用于单点登录(SSO),这一点和OAuth不同,OAuth主要用于授权,而SAML侧重身份认证。需要明确两者的区别,避免用户混淆。 接下来,用户可能需要了解SAML的工作流程,比如SP和IdP的角色,以及断言(Assertion)的类型。这里需要结构清晰,分步骤解释。同时,用户可能关心SAML的安全性,比如签名和加密机制,以及常见的漏洞和防护措施。 另外,用户可能想了解SAML的实际应用案例,比如企业内部的SSO系统,或者与OAuth的联合使用场景。这时候举一些例子会有帮助,比如使用SAML的公司或服务。 还需要注意用户的技术背景。如果用户是开发人员,可能需要更详细的技术细节,比如XML结构、绑定方式(HTTP POST/Redirect)。如果是管理人员,可能更关注应用场景和优势。 在回答结构上,可以按照核心概念、工作流程、安全机制、与OAuth的对比、应用案例和常见问题来组织。同时,使用之前用户接受的格式,比如分点、代码块、公式等,保持一致性。 需要检查是否有遗漏的关键点,比如SAML的版本差异(2.0是最常用的),或者与其他协议如OpenID Connect的关系。另外,可能用户会问到SAML的优缺点,比如XML的复杂性是否影响性能,或者在现代应用中的使用情况。 最后,确保语言简洁明了,避免过于技术化的术语,但必要时给出解释。保持回答的深度,但不过于冗长,帮助用户全面理解SAML协议。</think>$$SAML\ 协议框架$$ **SAML**(Security Assertion Markup Language)是一种基于**XML**的开放标准,专为实现跨域**单点登录(SSO)**和身份联合而设计。以下是深度解析: --- ### 一、核心目标与特性 1. **核心问题解决** $$ \exists \text{多系统} \Rightarrow \text{用户需重复登录} \Rightarrow \text{SAML提供:} \forall \text{系统} \Rightarrow \text{一次认证} $$ - 实现**身份提供者(IdP)**与**服务提供者(SP)**间的信任传递 2. **关键特性** ```markdown - XML数据格式(SAML 2.0为主流) - 支持HTTP POST/Redirect绑定 - 强依赖数字签名(防篡改) - 适用于企业级SSO(如Office 365登录) ``` --- ### 二、协议角色定义 1. **三大参与方** $$ \begin{cases} \text{主体 (Principal)} & \text{(用户)} \\ \text{身份提供者 (Identity Provider, IdP)} & \text{(如AD FS)} \\ \text{服务提供者 (Service Provider, SP)} & \text{(如Salesforce)} \end{cases} $$ 2. **断言(Assertion)结构** ```xml <!-- SAML断言示例 --> <saml:Assertion ID="_a75ad..." IssueInstant="2023-08-20T09:30:00Z"> <saml:Issuer>https://idp.example.com</saml:Issuer> <saml:Subject> <saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">user@example.com</saml:NameID> </saml:Subject> <saml:Conditions NotBefore="2023-08-20T09:30:00Z" NotOnOrAfter="2023-08-20T09:35:00Z"/> <saml:AuthnStatement AuthnInstant="2023-08-20T09:28:00Z"> <saml:AuthnContext> <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef> </saml:AuthnContext> </saml:AuthnStatement> </saml:Assertion> ``` - **断言类型**:认证声明、属性声明、授权决策 --- ### 三、标准交互流程(Web SSO) ```mermaid sequenceDiagram participant User as 用户 participant SP as 服务提供者 participant IdP as 身份提供者 User->>SP: 请求访问资源 SP->>User: 生成SAML请求 + 重定向到IdP User->>IdP: 提交认证(如AD凭证) IdP->>User: 生成SAML响应(含签名断言) User->>SP: 提交SAML响应 SP->>SP: 验证签名/时效性/颁发会话Cookie SP->>User: 授权访问资源 ``` --- ### 四、关键安全机制 1. **XML数字签名** - 签名流程: $$ \text{断言哈希} \rightarrow \text{私钥加密} \rightarrow \text{XML签名块} $$ ```xml <ds:Signature> <ds:SignedInfo>...</ds:SignedInfo> <ds:SignatureValue>MEUCIQD...</ds:SignatureValue> <ds:KeyInfo><ds:X509Data>...</ds:X509Data></ds:KeyInfo> </ds:Signature> ``` 2. **防御措施** ```markdown - 强制HTTPS传输 - 断言时效控制(NotBefore/NotOnOrAfter) - 防范重放攻击(ID唯一性校验) - SP严格验证IdP证书链 ``` --- ### 五、与OAuth 2.0对比 | 维度 | SAML 2.0 | OAuth 2.0 | |--------------------|-----------------------------------|-------------------------------------| | **核心目标** | 身份认证与SSO | 资源访问授权 | | **数据格式** | XML | JSON | | **传输协议** | 基于HTTP/SOAP | 基于HTTPS/RESTful | | **典型场景** | 企业内网SSO | 移动应用/API授权 | | **令牌类型** | SAML断言(长期有效) | Access Token(短期) | | **现代扩展** | SAML+WS-Federation | OpenID Connect | > **联合使用案例**: > $$ \text{企业SSO} \Rightarrow \text{SAML认证} \rightarrow \text{OAuth授权API访问} $$ > 如:先用SAML登录Azure AD,再获取OAuth令牌调用Microsoft Graph API --- ### 六、典型应用场景 1. **企业级SSO** - 微软AD FS配置SAML: ```powershell # 创建信赖方信任 Add-ADFSRelyingPartyTrust -Name "Salesforce" -MetadataUrl "https://login.salesforce.com/.xml" ``` 2. **跨域身份联合** - 高校联盟登录系统(如InCommon Federation) - 政府机构间身份互认 3. **云服务集成** - AWS IAM SAML配置: ```json { "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Principal": {"Federated": "arn:aws:iam::123456789012:saml-provider/MySAMLProvider"}, "Action": "sts:AssumeRoleWithSAML", "Condition": {"StringEquals": {"SAML:aud": "https://signin.aws.amazon.com/saml"}} }] } ``` --- ### 七、常见漏洞与缓解 1. **XML签名包装攻击** - 攻击原理: $$ \exists \text{恶意XML} \land \text{有效签名} \Rightarrow \text{SP误解析错误节点} $$ - 防护方案: ```markdown - 启用严格XML解析(禁用外部实体) - 校验断言位置与签名范围一致性 ``` 2. **断言重放攻击** - 防御措施: $$ \forall \text{断言ID} \Rightarrow \text{记录} \land \text{时效检查} $$ 3. **证书管理风险** - 最佳实践: ```markdown - IdP私钥存储HSM中 - SP定期轮换信任证书 - 禁用SHA-1算法 ``` --- ### 八、协议演进与替代方案 1. **SAML 2.0局限** ```markdown - XML处理复杂度高 - 移动端支持较弱 - 无法直接用于REST API ``` 2. **现代替代方案** - **OpenID Connect**:基于OAuth 2.0的身份层 $$ \text{OIDC} \approx \text{JSON Web Token} + \text{标准化声明} $$ - **WS-Federation**:微软主导的SOAP方案 --- SAML仍广泛用于企业级SSO场景,但新系统设计建议优先评估OIDC。实施时需重点关注**XML安全解析**和**证书生命周期管理**,推荐使用经过审计的库(如Spring Security SAML、OneLogin工具包)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值