安全声明标记语言SAML2.0初探
简介
SAML的全称是Security Assertion Markup Language, 是由OASIS制定的一套基于XML格式的开放标准,用在身份提供者(IdP)和服务提供者 (SP)之间交换身份验证和授权数据。
SAML的一个非常重要的应用就是基于Web的单点登录(SSO)。
接下来我们一起来看看SAML是怎么工作的。
SAML的构成
在SAML协议中定义了三个角色,分别是principal:代表主体通常表示人类用户。identity provider (IdP)身份提供者和service provider (SP)服务提供者。
IdP的作用就是进行身份认证,并且将用户的认证信息和授权信息传递给服务提供者。
SP的作用就是进行用户认证信息的验证,并且授权用户访问指定的资源信息。
SAML的优势
为什么要使用SAML呢?
第一可以提升用户体验,如果系统使用SAML,那么可以在登录一次的情况下,访问多个不同的系统服务。这实际上也是SSO的优势,用户不需要分别记住多个系统的用户名和密码,只用一个就够了。
第二可以提升系统的安全性,使用SAML,我们只需要向IdP提供用户名密码即可,
第三用户的认证信息不需要保存在所有的资源服务器上面,只需要在在IdP中存储一份就够了。
SAML是怎么工作的
接下来,我们通过一个用SAML进行SSO认证的流程图,来分析一下SAML是怎么工作的。
根据请求方式有redirect和post的不同,使用SAML来进行SSO认证有通常有三种方式,我们一一道来。
SP redirect request; IdP POST response
上图中User Agent就是web浏览器,我们看一下如果用户想请求Service Provider的资源的时候,SAML协议是怎么处理的。
- 用户通过User Agent请求Service Provider,比如:
http://sp.flydean.com/myresource
SP将会对该资源进行相应的安全检查,如果发现已经有一个有效的安全上下文的话,SP将会跳过2-7步,直接进入第8步。
- 如果在第一步的时候,SP并没有找到相应的有效安全上下文的话,则会生成对应的SAMLRequest,并将User Agent重定向到IdP:
302 Redirect
Location: https://idp.flydean.com/SAML2/SSO/Redirect?SAMLRequest=request&RelayState=token
RelayState是SP维护的一个状态信息,主要用来防止CSRF攻击。
其中这个SAMLRequest是用Base64编码的samlp:AuthnRequest,下面是一个samlp:AuthnRequest的例子:
<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="2020-09-05T09:21:59Z"
AssertionConsumerServiceIndex="0"
AttributeConsumingServiceIndex="0">
<saml:Issuer>https://sp.flydean.com/SAML2</saml:Issuer>
<samlp:NameIDPolicy
AllowCreate="true"
Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient"/>
</samlp:AuthnRequest>
为了安全起见,SAMLRequest还可以使用SP提供的签名key来进行签名。
- User agent将会发送一个get请求到IdP的SSO server :
GET /SAML2/SSO/Redirect?SAMLRequest=request&RelayState=token HTTP/1.1
Host: idp.flydean.com
IdP收到这个AuthnRequest请求之后,将会进行安全验证,如果是合法的AuthnRequest,那么将会展示登录界面。
- 用户可以输入用户名密码进行登录。登录成功之后,IdP将会返回一个XHTML form:
<form method="post" action="https://sp.flydean.com/SAML2/SSO/POST" ...>
<input type="hidden" name="SAMLResponse" value="response" />
<input type="hidden" name="RelayState" value="token" />
...
<input type="submit" value="Submit" />
</form>
这个form中包含了SAMLResponse信息,SAMLResponse中包含了用户相关的信息。
同样的SAMLResponse也是使用Base64进行编码过的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="2020-09-05T09:22:05Z"
Destination="https://sp.flydean.com/SAML2/SSO/POST">
<saml:Issuer>https://idp.flydean.com/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="2020-09-05T09:22:05Z">
<saml:Issuer>https://idp.flydean.com/SAML2</saml:Issuer>
<!-- a POSTed assertion MUST be signed -->
<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.flydean.com/SAML2/SSO/POST"
NotOnOrAfter="2020-09-05T09:27:05Z"/>
</saml:SubjectConfirmation>
</saml:Subject>
<saml:Conditions
NotBefore="2020-09-05T09:17:05Z"
NotOnOrAfter="2020-09-05T09:27:05Z">
<saml:AudienceRestriction>
<saml:Audience>https://sp.flydean.com/SAML2</saml:Audience>
</saml:AudienceRestriction>
</saml:Conditions>
<saml:AuthnStatement
AuthnInstant="2020-09-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>
我们可以看到samlp:Response中包含有saml:Assertion信息。
user agent 收到XHTML form之后将会提交该form给SP。
SP中的assertion consumer service将会处理这个请求,创建相关的安全上下文,并将user agent重定向到要访问的资源页面。
user agent再次请求SP资源。
因为安全上下文已经创建完毕,SP可以直接返回相应的资源,不用再次到IdP进行认证。
我们可以看到上面的所有的信息交换都是由前端浏览器来完成的,在SP和IdP之间不存在直接的通信。
这种全部由前端来完成信息交换的方式好处就是协议流非常简单,所有的消息都是简单的GET或者POST请求。
如果为了提高安全性,也可以使用引用消息。也就是说IdP返回的不是直接的SAML assertion,而是一个SAML assertion的引用。SP收到这个引用之后,可以从后台再去查询真实的SAML assertion,从而提高了安全性。
SP POST Request; IdP POST Response
刚刚讲的是SP redirect Request,这里我们看一下SP POST request是怎么做的:
和第一种方式的不同之处在于第二步和第三步。
第二步:SP不再进行redirect了,而是返回一个XHTML form给User agent:
<form method="post" action="https://idp.flydean.com/SAML2/SSO/POST" ...>
<input type="hidden" name="SAMLRequest" value="request" />
<input type="hidden" name="RelayState" value="token" />
...
<input type="submit" value="Submit" />
</form>
第三步:拿到第二步的XHTML form之后,User agent将该form post到IdP SSO server。
从第四步开始就和第一种方式是一样的了。
SP redirect artifact; IdP redirect artifact
第三种方式,SP和IdP都用的是redirect,但是redirect的内容都是artifact。
之前我们讲了SAML message可以以值的方式也可以以引用的方式来进行传递。
而这种以引用的传递方式就是artifact。
收到artifact的receiver会发送一个samlp:ArtifactResolve 给issuer,从而获得真正的message。
下面是一个向IdP请求message的例子:
<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="2020-09-05T09:21:58Z">
<saml:Issuer>https://idp.flydean.com/SAML2</saml:Issuer>
<!-- an ArtifactResolve message SHOULD be signed -->
<ds:Signature
xmlns:ds="http://www.w3.org/2000/09/xmldsig#">...</ds:Signature>
<samlp:Artifact>AAQAAMh48/1oXIM+sDo7Dh2qMp1HM4IF5DaRNmDj6RdUmllwn9jJHyEgIi8=</samlp:Artifact>
</samlp:ArtifactResolve>
相应的server会返回一个包含samlp:AuthnRequest的samlp:ArtifactResponse:
<samlp:ArtifactResponse
xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
ID="_d84a49e5958803dedcff4c984c2b0d95"
InResponseTo="_cce4ee769ed970b501d680f697989d14"
Version="2.0"
IssueInstant="2020-09-05T09:21:59Z">
<!-- an ArtifactResponse message SHOULD be signed -->
<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="2020-09-05T09:21:59Z"
Destination="https://idp.flydean.com/SAML2/SSO/Artifact"
ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"
AssertionConsumerServiceURL="https://sp.flydean.com/SAML2/SSO/Artifact">
<saml:Issuer>https://sp.flydean.com/SAML2</saml:Issuer>
<samlp:NameIDPolicy
AllowCreate="false"
Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"/>
</samlp:AuthnRequest>
</samlp:ArtifactResponse>
看下第三种方式的流程图:
可以看到这种方式和前面两种方式的区别就是多了一个请求真实message的步骤。
以第三,四,五步为例:
第三步user agent请求IdP的SSO server:
https://idp.example.org/SAML2/SSO/Artifact?SAMLart=artifact_1&RelayState=token
注意这里请求的参数变成了SAMLart。
第四步,IdP需要发送一个samlp:ArtifactResolve到SP来请求真正的samlp:AuthnRequest。
第五步,SP返回一个samlp:ArtifactResponse 包含samlp:AuthnRequest。
总结
SAML协议和它的基本用法就是上面这样。下面的文章我们会举一个具体的例子,来讲解如何应用SAML协议。
本文作者:flydean程序那些事
本文链接:http://www.flydean.com/saml-startup/
本文来源:flydean的博客
欢迎关注我的公众号:「程序那些事」最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!
安全声明标记语言SAML2.0初探的更多相关文章
- XML 概述 (可扩展标记语言)
XML:eXtensible Markup Language 可扩展标记语言 概念:可扩展:xml中所有的标签都是自定义的.没有预定义的. 功能: 存储数据 ...
- 12XML(可扩展标记语言)
XML:eXtensible Markup Language 什么是标记语言?什么是标记? 标记(Markup):文档中任何不想被打印输出的部分(不是真正的文档内容,联想读书时做的“读书笔记”,在旁边 ...
- SAML2.0 协议初识(一)
一.什么是 SAML 协议? SAML 即安全断言标记语言,英文全称是 Security Assertion Markup Language.它是一个基于 XML 的标准,用于在不同的安全域(secu ...
- 模型标准化——预测模型标记语言(PMML)
https://www.cnblogs.com/pinard/p/9220199.html 在机器学习用于产品的时候,我们经常会遇到跨平台的问题.比如我们用Python基于一系列的机器学习库训练了一个 ...
- 超文本标记语言HTML
介绍html文档的基本结构,html常用标签的使用,理解html语言制作网页基本原理. html概述和基本结构 html概述 HTML是 HyperText Mark-up Language 的首字母 ...
- 理解Xaml标记语言
理解XAML XAML基于XAML,因而具有与XAML相似的特性.在XAMl中,同样必须区分大小写,但是Xaml以.xaml作为扩展名,表示这是一个应用程序的标记扩展文件.WPF中的XAML主要用于创 ...
- 标记语言XML
标记语言概述 标记语言,是一种将文本(Text)以及文本相关的其他信息结合起来,展现出关于文档结构和数据处理细节的电脑文字编码.一部分是标记,一部分是标记中的内容,两部分构成标记语言 <标记 ...
- XML(可拓展标记语言)
XML 是可扩展标记语言(Extensible Markup Language)的缩写,其中的 标记(markup)是关键部分.您可以创建内容,然后使用限定标记标记它,从而使每个单词.短语或块成为 ...
- XML简介——可扩展标记语言(Extensible Markup Language)
(What) XML是什么? XML指可扩展标记语言(Extensible Markup Language) 1. XML是一种标记语言,类似HTML. 2. XML具有自我描述性 3. XML ...
随机推荐
- Spring第二天,你必须知道容器注册组件的几种方式!学废它吊打面试官!
前一篇<不要再说不会Spring了!Spring第一天,学会进大厂!>文章可点击下方链接进行回看. 不要再说不会Spring了!Spring第一天,学会进大厂! 今天将继续讲解Spri ...
- Java web项目 上传图片保存到数据库,并且查看图片,(从eclipse上移动到tomact服务器上,之路径更改,包括显示图片和导出excel)
//项目做完之后,在本机电脑运行完全正常,上传图片,显示图片,导出excel,读取excel等功能,没有任何问题,但是,当打成war包放到服务器上时,这些功能全部不能正常使用. 最大的原因就是,本机测 ...
- .Net orm 开源项目 FreeSql 2.0.0(满意的答卷)
写在开头 2018年11月头脑发热到今天,一晃已经两年,当初从舒服区走向一个巨大的坑,回头一看后背一凉. 两年时间从无到有,经历数不清的日夜奋斗(有人问花了多长时间投入,答案:全职x2 + 两年无休息 ...
- PDF文档工具:pdfFactory快照功能详解
pdfFactory的快照功能,是通过一种类似截图的方式,将文档中的内容,如标题.图片.段落.文字等进行剪切的功能.剪切后的内容会转化为文本框的形式,我们可以对其进行加边框.旋转等编辑处理,但不能对其 ...
- 使用Folx下载任务完成后,怎么自动完成关闭
下载工具的优点是可以通过多线程的方式,提高文件的下载速度,减少用户的下载时间.但另一方面来说,下载工具为了达到高速下载,也会占据较多的带宽资源,甚至会拖慢电脑的运行. 因此,很多用户会利用电脑的空闲时 ...
- 网络系列之 cookie增删改查(封装)
什么是cookie 呢?简单来说,这个小东西,会记录你的 浏览器 浏览习惯,或 账号密码等, 以便于提高用户的体验感. 举个例子: 你们有没有发现,去淘宝一些购物网站, 你搜索了 椅子, 挑选了一会椅 ...
- k8s 自动伸缩 pod(HPA)
上一篇简单说了一下使用 kubeadm 安装 k8s.今天说一下 k8s 的一个神奇的功能:HPA (Horizontal Pod Autoscaler). HPA 依赖 metrics-server ...
- 蓝桥杯——分组比赛(2017JavaB组第3题)
分组比赛(17JavaB3) 9名运动员参加比赛,需要分3组进行预赛. 有哪些分组的方案呢? 标记运动员为 A,B,C,... I 下面的程序列出了所有的分组方法: ABC DEF GHI ABC D ...
- TIOBE 11月指数:C语言居首,稳居宝座,Python直逼第二!
官方网址:https://www.tiobe.com/tiobe-index/ 这是自近20年前TIOBE指数开始以来,Java和C第一次不再占据前两位.C仍然是第一位的,但是现在第二个位置是 ...
- mysql undo+redo+binlog
rt 数据库事务开始之前,会将要修改的记录存放到UNdo日志里,当事务回滚时或数据库崩溃时,可以利用undo日志撤销未提交事务对数据库产生的影响. 逻辑日志,记录一个过程,提交后不会删除.delete ...