简介

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协议是怎么处理的。

  1. 用户通过User Agent请求Service Provider,比如:
http://sp.flydean.com/myresource

SP将会对该资源进行相应的安全检查,如果发现已经有一个有效的安全上下文的话,SP将会跳过2-7步,直接进入第8步。

  1. 如果在第一步的时候,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来进行签名。

  1. User agent将会发送一个get请求到IdP的SSO server :
GET /SAML2/SSO/Redirect?SAMLRequest=request&RelayState=token HTTP/1.1
Host: idp.flydean.com

IdP收到这个AuthnRequest请求之后,将会进行安全验证,如果是合法的AuthnRequest,那么将会展示登录界面。

  1. 用户可以输入用户名密码进行登录。登录成功之后,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信息。

  1. user agent 收到XHTML form之后将会提交该form给SP。

  2. SP中的assertion consumer service将会处理这个请求,创建相关的安全上下文,并将user agent重定向到要访问的资源页面。

  3. user agent再次请求SP资源。

  4. 因为安全上下文已经创建完毕,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:AuthnRequestsamlp: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初探的更多相关文章

  1. XML 概述 (可扩展标记语言)

    XML:eXtensible Markup Language  可扩展标记语言 概念:可扩展:xml中所有的标签都是自定义的.没有预定义的.        功能:            存储数据   ...

  2. 12XML(可扩展标记语言)

    XML:eXtensible Markup Language 什么是标记语言?什么是标记? 标记(Markup):文档中任何不想被打印输出的部分(不是真正的文档内容,联想读书时做的“读书笔记”,在旁边 ...

  3. SAML2.0 协议初识(一)

    一.什么是 SAML 协议? SAML 即安全断言标记语言,英文全称是 Security Assertion Markup Language.它是一个基于 XML 的标准,用于在不同的安全域(secu ...

  4. 模型标准化——预测模型标记语言(PMML)

    https://www.cnblogs.com/pinard/p/9220199.html 在机器学习用于产品的时候,我们经常会遇到跨平台的问题.比如我们用Python基于一系列的机器学习库训练了一个 ...

  5. 超文本标记语言HTML

    介绍html文档的基本结构,html常用标签的使用,理解html语言制作网页基本原理. html概述和基本结构 html概述 HTML是 HyperText Mark-up Language 的首字母 ...

  6. 理解Xaml标记语言

    理解XAML XAML基于XAML,因而具有与XAML相似的特性.在XAMl中,同样必须区分大小写,但是Xaml以.xaml作为扩展名,表示这是一个应用程序的标记扩展文件.WPF中的XAML主要用于创 ...

  7. 标记语言XML

    标记语言概述 标记语言,是一种将文本(Text)以及文本相关的其他信息结合起来,展现出关于文档结构和数据处理细节的电脑文字编码.一部分是标记,一部分是标记中的内容,两部分构成标记语言   <标记 ...

  8. XML(可拓展标记语言)

      XML 是可扩展标记语言(Extensible Markup Language)的缩写,其中的 标记(markup)是关键部分.您可以创建内容,然后使用限定标记标记它,从而使每个单词.短语或块成为 ...

  9. XML简介——可扩展标记语言(Extensible Markup Language)

    (What) XML是什么? XML指可扩展标记语言(Extensible Markup Language) 1.  XML是一种标记语言,类似HTML. 2.  XML具有自我描述性 3.  XML ...

随机推荐

  1. BurpSuite 抓安卓app包

    认准夜神安卓模拟器,下了几个其他的模拟器都没有代理的功能 一.夜神安卓模拟器设置代理 1.点击右下角的设置 2.点击设置,进入到WIFI连接选项 3.进入列表后,鼠标点击wifi位置,长按左键,会出现 ...

  2. Hbase启动报java异常

    在conf文件夹下的hbase-env.sh文件中的j添加ava_home的环境变量, ******************************************************** ...

  3. 牛客练习赛60E 旗鼓相当的对手

    dsu on tree 题目链接 点我跳转 题目大意 给你一棵以\(1\)为根节点,包含\(n\)个节点的树和一个参数 \(k\),求每个节点的"\(rating\)" \(rat ...

  4. Camtasia处理音频制作BGM

    我们在剪辑自己录制的视频时经常会需要同时对音频进行处理,camtasia是一个可以对视频的音频或者单独的音频文件进行处理的软件,那我们就来看看到底如何使用camtasia 2019(Win)来处理音频 ...

  5. 插件SimSynth合成器功能介绍

    本章节采用图文结合的方式给大家介绍下电音编曲软件"水果"FL Studio中SimSynth合成器的功能介绍,感兴趣的朋友可以一起进来沟通交流哦. SimSynth插件是FL St ...

  6. MathType中怎么打约化普朗克常数ħ

    普朗克常数记为ħ,是一个物理常数,用以描述量子大小.在量子力学中占有重要的角色,马克斯·普朗克在1900年研究物体热辐射的规律时发现的.如果要打出关于约化普朗克常数ħ的公式,就需要用到专业的公式编辑器 ...

  7. mongodb查询前10条

    mongo可以通过时间或者通过id来判断上一条记录或者下一条记录,我是通过id 前10条 db.数据库名称.find({ '_id': { '$lt': ids } }).sort({_id: -1} ...

  8. JDBC事务提交机制以及解决方案

    JDBC中的事务是自动提交的,什么是自动提交? 只要任意执行一条DML语句,则自动提交一次.这是JDBC默认的事务行为.但是实际业务当中,通常都是N条DML语句共同联合才能完成的,必须保证它们这些DM ...

  9. 啊这......蚂蚁金服被暂缓上市,员工的大house没了?

      没有想到,网友们前两天才对蚂蚁员工人均一套大 House羡慕嫉妒恨,这两天又因为蚂蚁金服被叫停惋惜.小编看了一下上一篇的时间,正好是11月3日晚上被叫停.太难了!   这中间出现了什么变故呢?原本 ...

  10. 经典面试题解析:这道 C 编程面试题居然有如此多的解法!

    问题描述 任意给定一个32位无符号整数n,求n的二进制表示中1的个数,比如n = 5(0101)时,返回2,n = 15(1111)时,返回4 这也是一道比较经典的题目了,相信不少人面试的时候可能遇到 ...