SAML和OAuth2这两种SSO协议的区别

简介

SSO是单点登录的简称,常用的SSO的协议有两种,分别是SAML和OAuth2。本文将会介绍两种协议的不同之处,从而让读者对这两种协议有更加深入的理解。

SAML

SAML的全称是Security Assertion Markup Language, 是由OASIS制定的一套基于XML格式的开放标准,用在身份提供者(IdP)和服务提供者 (SP)之间交换身份验证和授权数据。

SAML的一个非常重要的应用就是基于Web的单点登录(SSO)。

在SAML协议中定义了三个角色,分别是principal:代表主体通常表示人类用户。identity provider (IdP)身份提供者和service provider (SP)服务提供者。

IdP的作用就是进行身份认证,并且将用户的认证信息和授权信息传递给服务提供者。

SP的作用就是进行用户认证信息的验证,并且授权用户访问指定的资源信息。

接下来,我们通过一个用SAML进行SSO认证的流程图,来分析一下SAML是怎么工作的。

image

上图中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,从而提高了安全性。

SAML的缺点

SAML协议是2005年制定的,在制定协议的时候基本上是针对于web应用程序来说的,但是那时候的web应用程序还是比较简单的,更别提对App的支持。

SAML需要通过HTTP Redect和HTTP POST协议来传递用户信息,并且通常是通过HTML FORM的格式来进行数据的提交的。如果应用程序并不是web应用,比如说是一个手机App应用。

这个手机APP应用的启动链接是 my-photos://authenticate , 但是手机app可能并不能获取到Http POST的body内容。他们只能够通过URL来进行参数的传递。

这就意味着,在手机APP中不能够使用SAML。

当然,要想工作也可以,不过需要进行一些改造。比如通过第三方应用对POST消息进行解析,然后将解析出来的SAMLRequest以URL参数的形式传递给APP。

另一种方法就是使用OAuth2.

OAuth2

因为Oauth2是在2012年才产生的。所以并没有那么多的使用限制。我们可以在不同的场合中使用OAuth2。

我们先来看一下OAuth2中授权的流程图:

image

一般来说OAuth2中有4个角色。

resource owner: 代表的是资源的所有者,可以通过提供用户名密码或者其他方式来进行授权。通常来是一个人。

resource server:代表的是最终需要访问到资源的服务器。比如github授权之后获取到的用户信息。

client: 用来替代resource owner来进行交互的客户端。

authorization server: 用来进行授权的服务器,可以生成相应的Access Token。

整个流程是这样的:

Client向resource owner发起一个授权请求,resource owner输入相应的认证信息,将authorization grant返回给client。

client再将获取到的authorization grant请求授权服务器,并返回access token。

client然后就可以拿着这个access token去请求resource server,最后获取到受限资源。

OAuth2的缺点

OAuth2并没有指定Resource Server怎么和Authorization Server进行交互。也没有规定返回用户信息的内容和格式。这些都需要实现方自己去决定。

OAuth2默认是在HTTPS环境下工作的,所以并没有约定信息的加密方式。我们需要自己去实现。

最后,OAuth2是一个授权协议,而不是认证协议。对于这个问题,其实我们可以考虑使用OpenID Connect协议。因为OpenID Connect就是基于OAuth2实现的,并且添加了认证协议。

OpenID Connect简称为OIDC,已成为Internet上单点登录和身份管理的通用标准。 它在OAuth2上构建了一个身份层,是一个基于OAuth2协议的身份认证标准协议。

OAuth2实际上只做了授权,而OpenID Connect在授权的基础上又加上了认证。

OIDC的优点是:简单的基于JSON的身份令牌(JWT),并且完全兼容OAuth2协议。

两者的对比

在SAML协议中,SAML token中已经包含了用户身份信息,但是在OAuth2,在拿到token之后,需要额外再做一次对该token的校验。

但是另一方面,OAuth2因为需要再做一次认证,所以可以在 Authorization Server 端对token进行无效处理。

CAS简介

做过SSO的应该都听说过CAS。CAS的全称是Central Authentication Service,是一个企业级的开源的SSO认证框架。

CAS内部集成了CAS1,2,3,SAML1,2,OAuth2,OpenID和OpenID Connect协议,非常的强大。我们会在后面的文章中介绍CAS的使用。

本文作者:flydean程序那些事

本文链接:http://www.flydean.com/saml-vs-oauth2/

本文来源:flydean的博客

欢迎关注我的公众号:「程序那些事」最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容