简介

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

OAuth2实际上只做了受权,而OpenID Connect在受权的根底上又加上了认证。

OIDC的长处是:简略的基于JSON的身份令牌(JWT),并且齐全兼容OAuth2协定。

明天咱们将会介绍一下OIDC的具体原理。

OpenID Connect是什么

OpenID Connect公布于2014年,是建设在OAuth 2.0协定之上的简略身份层,它容许客户端基于受权服务器或身份提供商(IdP)进行的身份验证来验证最终用户的身份,并取得用户的相干信息。

OpenID Connect提供了RESTful HTTP API,并应用Json作为数据的传递格局。

之前咱们讲到了基于XML格局的SAML协定,而OpenID Connect因为其更加简洁的数据交换格局,被越来越多的利用应用,曾经成为事实上的规范。

咱们看一下OpenID connect的根本流程:

  1. RP(client)发送一个认证申请到 OpenID Provider(OP)。
  2. OP对End User进行认证并取得相应的受权。
  3. OP返回一个ID Token或者access Token给RP。
  4. RP应用access token向UserInfo Endpoint申请用户信息。
  5. UserInfo Endpoint返回相应的用户信息给RP。

ID Token

ID Token就像是一个用户的身份证,它是以JWT格局存在的,并且由OP进行签名,保障它的安全性。

获取ID Token的形式就是向OP发送认证申请。

因为ID Token是以JWT格局存在的,JWT能够分为三个局部,别离是Header,Payload和Signature。

这里咱们次要关注一下Payload的json内容:

{  "sub"       : "alice",  "iss"       : "https://openid.flydean.com",  "aud"       : "client-12345",  "nonce"     : "n-0S6_WzA2Mj",  "auth_time" : 1311280969,  "acr"       : "c2id.loa.hisec",  "iat"       : 1311280970,  "exp"       : 1311281970}
  • sub = Subject Identifier:必须。iss提供的EU的惟一标识;最长为255个ASCII个字符;
  • iss = Issuer Identifier:必须。提供认证信息者的惟一标识。个别是Url的host+path局部;
  • aud = Audience(s):必须。标识ID-Token的受众。必须蕴含OAuth2的client_id;
  • nonce:RP发送申请的时候提供的随机字符串,用来减缓重放攻打,也能够来关联ID-Token和RP自身的Session信息。
  • auth_time = AuthenticationTime:EU实现认证的工夫。如果RP发送认证申请的时候携带max_age的参数,则此Claim是必须的。
  • acr = Authentication Context Class Reference:可选。示意一个认证上下文援用值,能够用来标识认证上下文类。
  • iat = Issued At Time:必须。JWT的构建的工夫。
  • exp = Expiration time:必须。ID-Token的过期工夫;

下面的是ID Token的规范Claims。

申请ID Token

当初咱们晓得了ID Token是什么,那么在OpenID Connect的RP客户端如何申请一个ID Token呢?

尽管OpenID Connect并未指定应如何理论验证用户身份,这取决于提供者来决定。然而咱们通常由Web浏览器来执行认证步骤。

浏览器将用户重定向到认证服务器的认证窗口,用户输出用户名和明码之后,通过OAuth 2.0协定申请ID token。

应用OAuth 2.0来获取ID Token有3种形式:

  1. Authorization Code模式

Authorization Code流程的步骤如下:

客户端筹备身份认证申请,申请里蕴含所须要的参数

客户端发送申请到受权服务器

受权服务器对最红用户进行身份认证

受权服务得最终用户的对立/受权

受权服务器把最终用户发送回客户端,同时带着受权码

客户端应用受权码向Token端点申请一个响应

客户端接管到响应,响应的Body外面蕴含在和ID Token和Access Token

客户端验证ID Token,并取得用户的一些身份信息

  1. 隐式受权

上图就是一个隐式受权的例子,和Authorization Code模式不同的是,认证服务器返回的是一个access token片段,只有这个片段,咱们是无奈失去access token的。

这里咱们须要额定申请一次client resource服务器,服务器将会返回一个script脚本,通过这个脚本,咱们对access token片段进行解析,失去最终的access token。

  1. 混合模式

混合模式比拟少用到,它是后面两种模式的混合,它容许从前端和后端别离获取token值。

ID Token能够做什么

那么咱们拿到申请失去的ID Token能够做什么事件呢?

  1. 无状态session,通过将token存储在浏览器的cookie中,咱们能够实现轻量级的无状态会话。

服务器端不须要存储会话信息,咱们只须要在服务器端对token进行验证即可。

  1. 能够将token传递给第三方,因为token自身并不是敏感信息,所以咱们能够将token传递给其余应用程序或者后端服务。
  2. 令牌交互,咱们能够通过ID Token去IdP服务器中申请access token,从而起到了交互token的目标。

Open Connect认证码受权的例子

这里咱们举一个应用认证码受权获取到ID token的例子。

  1. RP通过重定向到OpenID Provider的OAuth 2.0认证终端,来初始化一个用户认证。

上面是一个重定向的例子:

HTTP/1.1 302 FoundLocation: https://openid.flydean.com/login?          response_type=code          &scope=openid          &client_id=s6BhdRkqt3          &state=af0ifjsldkj          &redirect_uri=https%3A%2F%2Fclient.flydean.com%2Fcb
  • response_type:因为咱们是认证码模式,这里抉择code
  • scope:openid示意申请的是openid。
  • client_id:RP的client id,OP通过这个client_id来辨认是否是可辨认的RP。能够提前注册或者提前约定。
  • state:RP生成的一个状态规范,次要为了避免攻打。
  • redirect_uri:认证结束之后,跳转的链接。

在OP端,将会检测是否曾经存在一个无效的用户session,否则将会弹出用户登录界面,让用户登录。

登录胜利之后,client将会重定向到redirect_uri,并带上认证码:

HTTP/1.1 302 FoundLocation: https://client.flydean.com/cb?          code=SplxlOBeZQQYbYS6WxSbIA          &state=af0ifjsldkj
  1. 应用code获取ID token

下面返回的code只是一个两头产物,RP须要将code提交给OP换取ID token。

这次咱们间接应用一个后端的POST申请:

POST /token HTTP/1.1Host: openid.flydean.comContent-Type: application/x-www-form-urlencodedAuthorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JWgrant_type=authorization_code &code=SplxlOBeZQQYbYS6WxSbIA &redirect_uri=https%3A%2F%2Fclient.flydean.com%2Fcb
  • grant_type:authorization_code示意是受权码格局
  • code就是下面一步取得的code
  • redirect_uri是callback url

如果胜利,OP会返回一个JSON对象,带有ID token, access token 或者 refresh token:

HTTP/1.1 200 OKContent-Type: application/jsonCache-Control: no-storePragma: 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的格局是JWT。

User Info

咱们获取到的ID token外面曾经蕴含了一些十分有用的claims信息。

事实上ID Token还能够蕴含其余的user info信息:

比方name,profile,picture,email,gender,birthdate,phone_number,address等等有用的信息。

咱们能够在token申请的时候增加上额定的scope:

HTTP/1.1 302 FoundLocation: https://openid.flydean.com/login?          response_type=code          &scope=openid%20email          &client_id=s6BhdRkqt3          &state=af0ifjsldkj          &redirect_uri=https%3A%2F%2Fclient.flydean.com%2Fcb

比方下面的例子中,咱们增加了额定的email信息,那么OP将会在token中退出email选项。

比方:

{   "sub"                     : "alice",   "email"                   : "alice@wonderland.net",   "email_verified"          : true,   "name"                    : "Alice Adams",   "given_name"              : "Alice",   "family_name"             : "Adams",   "phone_number"            : "+86 18888888888",   "profile"                 : "https://flydean.com/users/alice"}
本文作者:flydean程序那些事

本文链接:http://www.flydean.com/openid-connect-startup/

本文起源:flydean的博客

欢送关注我的公众号:「程序那些事」最艰深的解读,最粗浅的干货,最简洁的教程,泛滥你不晓得的小技巧等你来发现!