OpenId Connect与OAuth

OAuth是一个授权流程,通过一系列交互,获取到access token用于访问资源。

OpenId Connect是对OAuth的扩展,添加了认证这一功能。

ID Token

OpenId Connect的认证是基于ID Token这一个对象,ID Token标志了当前的用户是谁,以及用户的相关信息。OpenId Connect的流程,基本就是获取ID Token的流程。

ID Token一般为json格式:

{
  "sub"       : "alice",
  "iss"       : "https://openid.c2id.com",
  "aud"       : "client-12345",
  "nonce"     : "n-0S6_WzA2Mj",
  "auth_time" : 1311280969,
  "acr"       : "c2id.loa.hisec",
  "iat"       : 1311280970,
  "exp"       : 1311281970
}

其中:

  • sub 用户id
  • iss token的颁发者
  • aud token的接收client,第三方应用
  • iat,exp 有效、失效时间

与OAuth的关系

以OAuth中常见的code授权流程为例。OAuth流程可简化描述为

  • 首先通过前台交互,引导用户与服务器认证。
  • 服务器返回授权码后,应用后台通过授权码,再次请求服务器,获得access token

而对于OpenId Connect,区别在于,第一部请求时,scope参数会增加一个openid的值,如:

HTTP/1.1 302 Found
Location: https://openid.c2id.com/login?
          response_type=code
          **&scope=openid**
          &client_id=s6BhdRkqt3
          &state=af0ifjsldkj
          &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb

这样服务器返回的code中也会包含相应的信息, 在第二部将授权码发给服务器时,服务器会额外返回Id Token字段:

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache

{
  "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,
}

携带额外信息

ID token中包含了用户id,有效时间,可以看作一个服务器版的cookie,当未过期时,如果用这个token请求资源,服务器便可用通过验证token有效性,认为当前请求处于登录已认证状态。

除此之外,在ID Token中,可以额外携带用户相关的信息:

  • 标准定义的信息
    - email
    - phone
    - profile:用户姓名等信息
    - address
  • 其他服务器添加字段

当然这些信息,都是需要第一步请求服务器获取授权码时,先在请求的参数scope里额外增加如email,phone等等。

我们使用第三方应用,通过微信、google等登录时,会告诉我们该应用希望获取用户信息存储控件等信息,并询问是否同意,这就是这些第三方应用请求了这些额外的scope

一个携带了额外信息的ID Token

{
   "sub"                     : "alice",
   "email"                   : "alice@wonderland.net",
   "email_verified"          : true,
   "name"                    : "Alice Adams",
   "given_name"              : "Alice",
   "family_name"             : "Adams",
   "phone_number"            : "+359 (99) 100200305",
   "profile"                 : "https://c2id.com/users/alice",
   "https://c2id.com/groups" : [ "audit", "admin" ]  //这个是一个非标准的scope信息
}

endpoint

endpoint是协议中定义的授权服务器的一些标准请求地址,一般接入OP(OpenId Provider)时,服务商会在接入说明的页面提供出来相应端点的地址。

  • Authorisation endpoint :第一步获取授权码的地址
  • Token endpoint : 第二部请求ID Token的地址,对于OAuth流程中,也就是请求access token的地址。
  • UserInfo endpoint : 可以通过该节点,获取之前请求的用户信息。与上一个Token endpoint不同点在于,Token endpoint返回的ID token中,可能无法携带所有的之前请求的用户信息,比如电话、地址等。而通过这个节点获取到的信息更加完整。
posted @ 2020-06-28 13:51  mosakashaka  阅读(352)  评论(0编辑  收藏  举报