OAuth & OpenID & SAML 工作流程梳理对比

2019-04-01  本文已影响0人  蒋扬海

我们经常会提到到SSO,OAuth,OpenID,SAML,一时间会让人摸不清他们之间的关系和区别,最近简单粗浅的研究了一下,分享出来。还有很多问题没来得及搞清楚,希望与大家一起讨论学习!

OAuth

OAuth 是由 Google 和 Twitter 合作开发的相对较新的认证授权标准(相比SAML),到现在被广泛使用的是OAuth2.0 版本。

使用场景:

我们在使用一些网站和手机应用的时候,往往需要填写各种信息和资料注册用户,这让很多人望而却步。利用第三方进行认证授权会让用户体验大大提升,并且也能降低系统的开发难度,减少开发成本。如今有很多互联网产品,比如,微信,QQ,新浪等拥有大量的用户,它们顺理成章的成为了第三方认证服务提供者。

下面的这种界面你一定不陌生:

20180330104453911.jpg qq_login.png

这里使用 QQ 登录 CSDN,并且 CSDN 被授权获取用户的QQ昵称,头像和性别。

等等,在近一步讲解之前,我们先要知道OAuth的几个基本概念:

四种模式

英文中用的是Flow,每一种Flow对应的不同的工作流程,不知道为啥被翻译成模式!

auth_code_flow.png

第一个模式花了较多的口水讲解,后面的你可别指望了了哈!!!

implicit_flow.png

​ 隐式模式是个什么鬼,它跟授权码模式的区别是什么?先看请求:

https://AUTHORIZATION_SERVER_URL/v1/oauth/authorize?
    response_type=token&
    client_id=CLIENT_ID&
    redirect_uri=CALLBACK_URL&
    scope=read

​ 注意哦,这里的 response_typetoken,表示要请求一个 access_token。直接找认证服务器要 token,并且也没有带上授权码模式请求中的client_secret,你牛!

​ 第三步的认证服务器重定向到https://CLIENT_URL/callback#token=ACCESS_TOKEN, 注意这里面有个 #号哦!你回头去看看上一种模式里面跳转的URL长什么样??

​ 第四步浏览器跟着重定向URL回到客户端(Client),但却并没有把 Token 直接带过去,token 被留在了浏览器里!

​ 第五步,客户端(Client) 使用 JavaScript 从浏览器里提取出 token

​ 第六步,浏览器将 token 正式交给客户端(Client)

关于隐式模式你可能会问,为啥要这么干?我的回答是“这是一个好问题!” 接着就交给你自己去找到答案吧,反正我没去研究过!如果你找到了答案,还麻烦给我留言~ 我是个懒人!!!

​ 对了,补上一张这个模式的时序图:

oauth_user_agent_flow.png oauth_client_credentials_flow.png

​ 请求如下:

https://AUTHORIZATION_SERVER_URL/v1/oauth/token?
    grant_type=client_credentials&
    client_id=CLIENT_ID&
    client_secret=CLIENT_SECRET

​ 客户端模式倒是简单,不需要用户提供账号密码,只需要提供客户端的账号密码(就是 CSDN 在 QQ 那边注册时得到的作为唯一表示的client_idclient_secret但如果是这样的话客户端咋知道使用的第三方(QQ) 的那个用户呢?有待继续研究吧~ 如果我还记得起来这个问题!

讲了这么多,也许你已经看累了,但我想强调一下这篇文章的标题是 《OAuth & OpenID & SAML 工作流程梳理对比》,是对比,对比,对比!请休息一下,整理好心情,接着往下看~

OpenID

OpenID 是基于 OAuth 协议的,在工作流程上跟OAuth很相近。OpenID的版本有OpenID 1.0,OpenID 2.0,OpenID connection

概念:

OpenID 有三种模式 (我们只讲第一种,后面的请自行查阅资料):

在讲下一步之前,先告诉你两点:

获取id_token请求如下:

POST /token HTTP/1.1
Host: AUTHORIZATION_SERVER_URL
Content-Type: application/x-www-form-urlencoded
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW

https://AUTHORIZATION_SERVER_URL/token?
  grant_type=authorization_code&
  code=AUTHORIZATION_CODE&
  redirect_uri=REDIRECT_URL

这里你会发现请求中没有client_idclient_secret,他们是通过 Header 中的 Authorization字段传递的。请求返回:

 {
  "id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjFlOWdkazcifQ.ewogImlzc
    yI6ICJodHRwOi8vc2VydmVyLmV4YW1wbGUuY29tIiwKICJzdWIiOiAiMjQ4Mjg5
    NzYxMDAxIiwKICJhdWQiOiAiczZCaGRSa3F0MyIsCiAibm9uY2UiOiAibi0wUzZ
    fV3pBMk1qIiwKICJleHAiOiAxMzExMjgxOTcwLAogImlhdCI6IDEzMTEyODA5Nz
    AKfQ.ggW8hZ1EuVLuxNuuIJKX_V8a_OMXzR0EHR9R6jgdqrOOF4daGU96Sr_P6q
    Jp6IcmD3HP99Obi1PRs-cwh3LO-p146waJ8IhehcwL7F09JdijmBqkvPeB2T9CJ
    NqeGpe-gccMg4vfKjkM8FcGvnzZUN4_KSP0aAp1tOJ1zZwgjxqGByKHiOtX7Tpd
    QyHE5lcMiKPXfEIQILVq0pc_E2DzL7emopWoaoZTF_m0_N0YzFC6g6EJbOEoRoS
    K5hoDalrcvRYLSrQAZZKflyuVCyixEoV9GfNQC3_osjzw2PAithfubEEBLuVVk4
    XUVrWOLrLl0nx7RkKU8NXNHq-rvKMzqg"
  "access_token": "SlAV32hkKG",
  "token_type": "Bearer",
  "expires_in": 3600,
}

SAML

SAML 是比较早的协议,有1.0,2.0版本,采用XML格式传递请求和返回数据。

基本概念:

以下是SAML的基础工作流程图:

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

以下的步奏讲解参考了: https://www.cnblogs.com/shuidao/p/3463947.html

samel_workflow.png

断言的格式大概如下:

<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>

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>

SAML本身含有很多不同变种的流程,这里演示的是最基本的一个,方便理解!

小结

OpenID OAuth SAML
Dates from 2005 2006 2001
Current version OpenID Connect OAuth 2.0 SAML 2.0
Main purpose Single sign-on for consumers API authorization between applications Single sign-on for enterprise users
Protocols used XRDS, HTTP JSON, HTTP SAM, XML, HTTP, SOAP

这三个概念本身包含的内容还远不止于此,篇(因)幅(为)有(懒)限(惰),就写这么一些基本的东西。如果你有兴趣近一步加深理解,可以参考以下这些链接:

也欢迎你留言参与讨论,有很多问题我也还没了解透彻,希望能有人传道授业解惑!

上一篇下一篇

猜你喜欢

热点阅读