本文将对OpenID Connect(OIDC)做一个简单介绍。本文主线源自文章:OpenID Connect explained。
为了便于理解,请先阅读笔者的另外一篇文章oAuth2.0 简介。
本文将主要分为以下几个部分:
identity背景介绍
OpenID Connect特性
identity token
如何获得一个id token
酷炫的id token使用场景
id token获取流程案例
OpenID Connect关于用户信息的声明
OP提供的接口
与oAuth2.0的关系
1,identity背景介绍
各种应用都需要做用户验证。最简单的方式是在本地维护一个数据库,存放用户账户和证书等数据。这种方式对于业务来说可能会不太友好:
注册和账户创建过程本来就很无聊。对于很多电商网站来说,它们会允许非登陆用户添加购物车,然后让用户下单时再注册。乏味的注册流程可能会导致很多用户放弃购买。
对于那些提供多个应用的企业来说,让各个应用维护各自的用户数据库,不管从管理还是安全层面来说,都是一个很大的负担。
对于这个问题,更好的方案是将用户认证和授权这些事情交给专门的identity provider(idp)服务来处理。
google、facebook、twitter这些大厂,就为它们的注册用户提供了这类idp服务。一个网站可以通过使用这类idp服务来极大简化用户的注册和登录流程。
2,OpenID Connect特性
OpenID Connect在2014年发行。虽然它不是第一个idp标准,但从可用性、简单性方面来说,它可能是最好的。OpenID Connect从SAML和OpenID 1.0/2.0中做了大量借鉴。
oAuth2.0使用access token来授权三方应用访问受保护的信息。OpenID Connect遵循oAuth2.0协议流程,并在这个基础上提供了id token来解决三方应用的用户身份认证问题。OpenID Connect将用户身份认证信息以id token的方式给到三房应用。id token基于JWT(json web token)进行封装,具有自包含性、紧凑性和防篡改性等特点。三方应用在验证完id token的正确性后,可以进一步通过oAuth2授权流程获得的access token读取更多的用户信息。
OpenID Connect大获成功的秘诀:
容易处理的id token。OpenID Connect使用JWT来给应用传递用户的身份信息。JWT以其高安全性(防止token被伪造和篡改)、跨语言、支持过期、自包含等特性而著称,非常适合作为token来使用。
基于oAuth2.0协议。id token是经过oAuth2.0流程来获取的,这个流程即支持web应用,也支持原生app。
简单。OpenID Connect足够简单。但同时也提供了大量的功能和安全选项以满足企业级业务需求。
OpenID Connect所涉及的角色如下:
用户。
RP:Relying Party,申请授信信息的可信客户端(既上文中提到的三方应用)。
OP:OpenID Provider,提供身份认证的服务方,比如google和facebook等公司的系统。
id token:包含身份认证信息的JWT。
user info api,返回用户信息的接口,当RP使用id token来访问时,返回授权用户的信息。
3,identity token
id token的概念类似身份证,只不过是JWT的形式,并由OP签发。
id token具有如下属性:
说明是哪位用户,也叫做主题(sub)
说明token由谁签发的(iss)
是否是为某一个特殊的用户生成的(aud)
可能会包含一个随机数(nonce)
认证时间(auth_time),以及认证强度(acr)
签发时间(iat)和过期时间(exp)
可能包含额外的请求细节,比如名字和email地址等
是否包含数字签名,token的接收方可以验证这个签名
可以被加密
一个id token样例如下:
{
"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
}
id token的头部,包含签名等信息,则会被编码成base64格式,下面是一个例子:
eyJhbGciOiJSUzI1NiIsImtpZCI6IjFlOWdkazcifQ.ewogImlzcyI6ICJodHRw Oi8vc2VydmVyLmV4YW1wbGUuY29tIiwKICJzdWIiOiAiMjQ4Mjg5NzYxMDAxIiw KICJhdWQiOiAiczZCaGRSa3F0MyIsCiAibm9uY2UiOiAibi0wUzZfV3pBMk1qIi wKICJleHAiOiAxMzExMjgxOTcwLAogImlhdCI6IDEzMTEyODA5NzAKfQ.ggW8hZ 1EuVLuxNuuIJKX_V8a_OMXzR0EHR9R6jgdqrOOF4daGU96Sr_P6qJp6IcmD3HP9 9Obi1PRs-cwh3LO-p146waJ8IhehcwL7F09JdijmBqkvPeB2T9CJNqeGpe-gccM g4vfKjkM8FcGvnzZUN4_KSP0aAp1tOJ1zZwgjxqGByKHiOtX7TpdQyHE5lcMiKP XfEIQILVq0pc_E2DzL7emopWoaoZTF_m0_N0YzFC6g6EJbOEoRoSK5hoDalrcvR YLSrQAZZKflyuVCyixEoV9GfNQC3_osjzw2PAithfubEEBLuVVk4XUVrWOLrLl0 nx7RkKU8NXNHq-rvKMzqg
更多关于JWT的数据结构请参考RFC 7519。
4, 如何获得一个id token
上面介绍了id token是什么?那如何获取呢?
这个过程涉及到idp,也就是上面提到的google、facebook等公司,通过验证用户的session或者证书并做认证。而用户的session或者证书的可信载体则是浏览器。
浏览器弹出框对于web应用来说是将用户重定向到idp的一种比较好的方式。Android或者IOS app需要唤起本系统的浏览器来做这件事。嵌入式的web view不是一个可信的方式,因为没法阻止这个web view所在的app来窃取用户的密码等信息。用户认证应该永远使用独立于app的可信方式,比如系统的浏览器。
注意,OpenID Connect并不会特别说明用户该如何被认证,这个逻辑有idp自己决定。
id tokens通过oAuth2.0协议获得。oAuth的具体介绍详见笔者的另外一篇文章oAuth2.0 简介
获取id token的流程分为如下几类:
authorization code flow。这是最常用的流程,主要用在web应用以及原生app场景。id token主要依靠后端而不是前端比如javascript和OP进行交互来获取。
implicit flow。对于基于浏览器(javascript)的应用,它们往往没有后端,id token是直接从OP的重定向里面得到的(依靠前段代码)。
hybrid flow。上面两种方式的综合,前后端独立获取id token,这种方式很少使用。
三种流程的比较如下:
图片引用自https://connect2id.com/learn/openid-connect
5,酷炫的id token使用场景
id token能够用在很多除登陆外的其它场景:
无状态会话。把id token放在浏览器的cookie里,能很容易实现一个轻量级的无状态会话方式。这种方式将不再需要服务端存储session信息,便于管理和对后端服务进行扩展。而当这个id token过期后,也可以很容易从OP重新获取一个。
将身份信息传给RP。id token可以很方便地用来将用户身份信息传递给RP。
token交换。这个id token也可以用来从oauth2.0授权服务器获取一个access token。现实生活中也存在需要先认证再授权的情况,比如去酒店要先登记才会给你客房的钥匙。
6, id token获取流程案例
接下来,我们将介绍一个使用authorization code flow来获取id token的样例。关于implicit flow和hybrid flow的样例,可以参考:OpenID Connect spec.
这个样例分为如下两个步骤:
图片引用自https://connect2id.com/learn/openid-connect
6.1 step1
三方应用通过将浏览器重定向到OP(比如google)的oAuth2.0授权页面来发起一个用户授权请求。一个授权重定向url例子如下:
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
url参数说明:
response_type,如果值是code的话,说明是authorization code flow。
scope,用来说明希望访问用户账户信息的哪些部分。
client_id,RP在OP上注册时分配的client id。
state,一个随机字符串,用来在判断回调和请求之间是否一致。
redirect_uri ,用户授权成功之后,浏览器访问的重定向uri。
OP会先检查当前授权用户的session,如果没有session的话,会让弹出一个登陆框让用户先登陆。然后用户就可以进行授权选择了。
图片引用自https://connect2id.com/learn/openid-connect
OP接着会访问redirect_uri,并附带授权码code(成功情况下)。
HTTP/1.1 302 Found
Location: https://client.example.org/cb?
code=SplxlOBeZQQYbYS6WxSbIA
&state=af0ifjsldkj
RP在处理这个回调时,需要先验证随机字符串state的值是否正确。并尝试用code来获取id token。
6.2 step2
授权码code是一种中间证书,只有OP能理解它,三方应用是无法理解的。接下来,三方应用需要通过一个后台调用来用授权码code去向OP换取一个id token。
OP会提供一个接口来处理这个授权码换取id token逻辑。
POST /token HTTP/1.1
Host: openid.c2id.com
Content-Type: application/x-www-form-urlencoded
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
grant_type=authorization_code
&code=SplxlOBeZQQYbYS6WxSbIA
&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
参数说明如下:
grant_type,这里设置为authorization_code。
code,上面得到的授权码code。
redirect_uri,和第一步中的redirect uri一致。
如果OP成功处理了该请求,则会返回一个json对象,包含id token,access token和一个可选的refresh 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是一个JWT,格式为:
Header.Payload.Signature
计算逻辑为:
BASE64URL(UTF8(Header)) || '.' ||
BASE64URL(Payload) || '.' ||
BASE64URL(Signature)
三方应用在拿到id token后,可根据Payload内容验证token的有效性:
确保aud和三方应用的client id一致。
确保nonce和step1中的state字段一致。
确保exp不超过当前时间。
对于只是获得id token的业务场景,也就是只需要认证,那么上面的步骤就足够了。上面样例里面的access token可以被忽略。
而对于需要进一步获取用户个人信息的场景,则需要用access token来进一步交换用户信息。我们接下来会讨论这个话题。
7, OpenID Connect关于用户信息的声明
OpenID Connect对用户信息做了一些标准说明。主要用来给OP应该提供哪些用户信息提供一个标准。
图片引用自https://connect2id.com/learn/openid-connect
三方应用在请求获取用户信息时,在scope中指定范围即可:
HTTP/1.1 302 Found
Location: https://openid.c2id.com/login?
response_type=code
&scope=openid%20email
&client_id=s6BhdRkqt3
&state=af0ifjsldkj
&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
如果你是一名程序员,请尊重用户隐私,在请求时尽量按需设置scope,这样会更容易满足用户隐私方面的法律。
8,OP提供的接口
8.1 授权接口
用户通过这个这个功能来授权RP获取自己的身份信息和个人信息,比如email、电话号码等信息。
这个接口是所有接口里面唯一需要用户和OP进行互动的,而交互方式往往是通过浏览器弹出对话框让用户选择"同意"或者"拒绝"。
8.2 token接口
token功能点允许三方应用使用从授权功能点得到的授权码,来交换id token和 access token。
8.3 用户信息接口
三方应用可以使用access token来访问这个接口,然后获取用户的个人信息,比如email、电话号码和地址。
8.4 可选的接口
上面三类接口是最核心的接口,所有的OP都必须提供。
OP还可以提供下面这些可选的接口:
webfinger。可以使用用户的emai地址等信息来动态发现一个OP。
provider metadata。通过提供一个json文档,来描述当前这个provider提供的所有OpenID connect和oAuth2的相关功能。方便三方应用查询。
三方应用注册。用来注册三方应用的restful web api。注册完毕后给这个应用分配client id和 secret。
会话管理。用来判断一个已经登陆的用户是否还和OP之间保持了一个有效会话。
9, 与oAuth2.0的关系
oAuth2.0协议是用来获取对受保护的资源比如某些web api调用所需的access token的。OpenID Connect则利用了oAuth2.0的这个流程来允许RP(三方应用)获取用户的身份信息。这些信息是以JWT形式进行交互的id token。同时,OpenID Connect还允许RP用获取id token时由OP一并返回的access token来进一步获取用户的个人信息,比如email、手机号码等。
下面这张图可以大致提现OpenID Connect和oAuth2.0的关系。
图片引用自https://openid.net/connect/
上面就是本文想聊的内容,希望对大家理解OpenID Connect有所帮助。
为了便于理解,请先阅读笔者的另外一篇文章oAuth2.0 简介。
本文将主要分为以下几个部分:
identity背景介绍
OpenID Connect特性
identity token
如何获得一个id token
酷炫的id token使用场景
id token获取流程案例
OpenID Connect关于用户信息的声明
OP提供的接口
与oAuth2.0的关系
1,identity背景介绍
各种应用都需要做用户验证。最简单的方式是在本地维护一个数据库,存放用户账户和证书等数据。这种方式对于业务来说可能会不太友好:
注册和账户创建过程本来就很无聊。对于很多电商网站来说,它们会允许非登陆用户添加购物车,然后让用户下单时再注册。乏味的注册流程可能会导致很多用户放弃购买。
对于那些提供多个应用的企业来说,让各个应用维护各自的用户数据库,不管从管理还是安全层面来说,都是一个很大的负担。
对于这个问题,更好的方案是将用户认证和授权这些事情交给专门的identity provider(idp)服务来处理。
google、facebook、twitter这些大厂,就为它们的注册用户提供了这类idp服务。一个网站可以通过使用这类idp服务来极大简化用户的注册和登录流程。
2,OpenID Connect特性
OpenID Connect在2014年发行。虽然它不是第一个idp标准,但从可用性、简单性方面来说,它可能是最好的。OpenID Connect从SAML和OpenID 1.0/2.0中做了大量借鉴。
oAuth2.0使用access token来授权三方应用访问受保护的信息。OpenID Connect遵循oAuth2.0协议流程,并在这个基础上提供了id token来解决三方应用的用户身份认证问题。OpenID Connect将用户身份认证信息以id token的方式给到三房应用。id token基于JWT(json web token)进行封装,具有自包含性、紧凑性和防篡改性等特点。三方应用在验证完id token的正确性后,可以进一步通过oAuth2授权流程获得的access token读取更多的用户信息。
OpenID Connect大获成功的秘诀:
容易处理的id token。OpenID Connect使用JWT来给应用传递用户的身份信息。JWT以其高安全性(防止token被伪造和篡改)、跨语言、支持过期、自包含等特性而著称,非常适合作为token来使用。
基于oAuth2.0协议。id token是经过oAuth2.0流程来获取的,这个流程即支持web应用,也支持原生app。
简单。OpenID Connect足够简单。但同时也提供了大量的功能和安全选项以满足企业级业务需求。
OpenID Connect所涉及的角色如下:
用户。
RP:Relying Party,申请授信信息的可信客户端(既上文中提到的三方应用)。
OP:OpenID Provider,提供身份认证的服务方,比如google和facebook等公司的系统。
id token:包含身份认证信息的JWT。
user info api,返回用户信息的接口,当RP使用id token来访问时,返回授权用户的信息。
3,identity token
id token的概念类似身份证,只不过是JWT的形式,并由OP签发。
id token具有如下属性:
说明是哪位用户,也叫做主题(sub)
说明token由谁签发的(iss)
是否是为某一个特殊的用户生成的(aud)
可能会包含一个随机数(nonce)
认证时间(auth_time),以及认证强度(acr)
签发时间(iat)和过期时间(exp)
可能包含额外的请求细节,比如名字和email地址等
是否包含数字签名,token的接收方可以验证这个签名
可以被加密
一个id token样例如下:
{
"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
}
id token的头部,包含签名等信息,则会被编码成base64格式,下面是一个例子:
eyJhbGciOiJSUzI1NiIsImtpZCI6IjFlOWdkazcifQ.ewogImlzcyI6ICJodHRw Oi8vc2VydmVyLmV4YW1wbGUuY29tIiwKICJzdWIiOiAiMjQ4Mjg5NzYxMDAxIiw KICJhdWQiOiAiczZCaGRSa3F0MyIsCiAibm9uY2UiOiAibi0wUzZfV3pBMk1qIi wKICJleHAiOiAxMzExMjgxOTcwLAogImlhdCI6IDEzMTEyODA5NzAKfQ.ggW8hZ 1EuVLuxNuuIJKX_V8a_OMXzR0EHR9R6jgdqrOOF4daGU96Sr_P6qJp6IcmD3HP9 9Obi1PRs-cwh3LO-p146waJ8IhehcwL7F09JdijmBqkvPeB2T9CJNqeGpe-gccM g4vfKjkM8FcGvnzZUN4_KSP0aAp1tOJ1zZwgjxqGByKHiOtX7TpdQyHE5lcMiKP XfEIQILVq0pc_E2DzL7emopWoaoZTF_m0_N0YzFC6g6EJbOEoRoSK5hoDalrcvR YLSrQAZZKflyuVCyixEoV9GfNQC3_osjzw2PAithfubEEBLuVVk4XUVrWOLrLl0 nx7RkKU8NXNHq-rvKMzqg
更多关于JWT的数据结构请参考RFC 7519。
4, 如何获得一个id token
上面介绍了id token是什么?那如何获取呢?
这个过程涉及到idp,也就是上面提到的google、facebook等公司,通过验证用户的session或者证书并做认证。而用户的session或者证书的可信载体则是浏览器。
浏览器弹出框对于web应用来说是将用户重定向到idp的一种比较好的方式。Android或者IOS app需要唤起本系统的浏览器来做这件事。嵌入式的web view不是一个可信的方式,因为没法阻止这个web view所在的app来窃取用户的密码等信息。用户认证应该永远使用独立于app的可信方式,比如系统的浏览器。
注意,OpenID Connect并不会特别说明用户该如何被认证,这个逻辑有idp自己决定。
id tokens通过oAuth2.0协议获得。oAuth的具体介绍详见笔者的另外一篇文章oAuth2.0 简介
获取id token的流程分为如下几类:
authorization code flow。这是最常用的流程,主要用在web应用以及原生app场景。id token主要依靠后端而不是前端比如javascript和OP进行交互来获取。
implicit flow。对于基于浏览器(javascript)的应用,它们往往没有后端,id token是直接从OP的重定向里面得到的(依靠前段代码)。
hybrid flow。上面两种方式的综合,前后端独立获取id token,这种方式很少使用。
三种流程的比较如下:
图片引用自https://connect2id.com/learn/openid-connect
5,酷炫的id token使用场景
id token能够用在很多除登陆外的其它场景:
无状态会话。把id token放在浏览器的cookie里,能很容易实现一个轻量级的无状态会话方式。这种方式将不再需要服务端存储session信息,便于管理和对后端服务进行扩展。而当这个id token过期后,也可以很容易从OP重新获取一个。
将身份信息传给RP。id token可以很方便地用来将用户身份信息传递给RP。
token交换。这个id token也可以用来从oauth2.0授权服务器获取一个access token。现实生活中也存在需要先认证再授权的情况,比如去酒店要先登记才会给你客房的钥匙。
6, id token获取流程案例
接下来,我们将介绍一个使用authorization code flow来获取id token的样例。关于implicit flow和hybrid flow的样例,可以参考:OpenID Connect spec.
这个样例分为如下两个步骤:
图片引用自https://connect2id.com/learn/openid-connect
6.1 step1
三方应用通过将浏览器重定向到OP(比如google)的oAuth2.0授权页面来发起一个用户授权请求。一个授权重定向url例子如下:
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
url参数说明:
response_type,如果值是code的话,说明是authorization code flow。
scope,用来说明希望访问用户账户信息的哪些部分。
client_id,RP在OP上注册时分配的client id。
state,一个随机字符串,用来在判断回调和请求之间是否一致。
redirect_uri ,用户授权成功之后,浏览器访问的重定向uri。
OP会先检查当前授权用户的session,如果没有session的话,会让弹出一个登陆框让用户先登陆。然后用户就可以进行授权选择了。
图片引用自https://connect2id.com/learn/openid-connect
OP接着会访问redirect_uri,并附带授权码code(成功情况下)。
HTTP/1.1 302 Found
Location: https://client.example.org/cb?
code=SplxlOBeZQQYbYS6WxSbIA
&state=af0ifjsldkj
RP在处理这个回调时,需要先验证随机字符串state的值是否正确。并尝试用code来获取id token。
6.2 step2
授权码code是一种中间证书,只有OP能理解它,三方应用是无法理解的。接下来,三方应用需要通过一个后台调用来用授权码code去向OP换取一个id token。
OP会提供一个接口来处理这个授权码换取id token逻辑。
POST /token HTTP/1.1
Host: openid.c2id.com
Content-Type: application/x-www-form-urlencoded
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
grant_type=authorization_code
&code=SplxlOBeZQQYbYS6WxSbIA
&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
参数说明如下:
grant_type,这里设置为authorization_code。
code,上面得到的授权码code。
redirect_uri,和第一步中的redirect uri一致。
如果OP成功处理了该请求,则会返回一个json对象,包含id token,access token和一个可选的refresh 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是一个JWT,格式为:
Header.Payload.Signature
计算逻辑为:
BASE64URL(UTF8(Header)) || '.' ||
BASE64URL(Payload) || '.' ||
BASE64URL(Signature)
三方应用在拿到id token后,可根据Payload内容验证token的有效性:
确保aud和三方应用的client id一致。
确保nonce和step1中的state字段一致。
确保exp不超过当前时间。
对于只是获得id token的业务场景,也就是只需要认证,那么上面的步骤就足够了。上面样例里面的access token可以被忽略。
而对于需要进一步获取用户个人信息的场景,则需要用access token来进一步交换用户信息。我们接下来会讨论这个话题。
7, OpenID Connect关于用户信息的声明
OpenID Connect对用户信息做了一些标准说明。主要用来给OP应该提供哪些用户信息提供一个标准。
图片引用自https://connect2id.com/learn/openid-connect
三方应用在请求获取用户信息时,在scope中指定范围即可:
HTTP/1.1 302 Found
Location: https://openid.c2id.com/login?
response_type=code
&scope=openid%20email
&client_id=s6BhdRkqt3
&state=af0ifjsldkj
&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
如果你是一名程序员,请尊重用户隐私,在请求时尽量按需设置scope,这样会更容易满足用户隐私方面的法律。
8,OP提供的接口
8.1 授权接口
用户通过这个这个功能来授权RP获取自己的身份信息和个人信息,比如email、电话号码等信息。
这个接口是所有接口里面唯一需要用户和OP进行互动的,而交互方式往往是通过浏览器弹出对话框让用户选择"同意"或者"拒绝"。
8.2 token接口
token功能点允许三方应用使用从授权功能点得到的授权码,来交换id token和 access token。
8.3 用户信息接口
三方应用可以使用access token来访问这个接口,然后获取用户的个人信息,比如email、电话号码和地址。
8.4 可选的接口
上面三类接口是最核心的接口,所有的OP都必须提供。
OP还可以提供下面这些可选的接口:
webfinger。可以使用用户的emai地址等信息来动态发现一个OP。
provider metadata。通过提供一个json文档,来描述当前这个provider提供的所有OpenID connect和oAuth2的相关功能。方便三方应用查询。
三方应用注册。用来注册三方应用的restful web api。注册完毕后给这个应用分配client id和 secret。
会话管理。用来判断一个已经登陆的用户是否还和OP之间保持了一个有效会话。
9, 与oAuth2.0的关系
oAuth2.0协议是用来获取对受保护的资源比如某些web api调用所需的access token的。OpenID Connect则利用了oAuth2.0的这个流程来允许RP(三方应用)获取用户的身份信息。这些信息是以JWT形式进行交互的id token。同时,OpenID Connect还允许RP用获取id token时由OP一并返回的access token来进一步获取用户的个人信息,比如email、手机号码等。
下面这张图可以大致提现OpenID Connect和oAuth2.0的关系。
图片引用自https://openid.net/connect/
上面就是本文想聊的内容,希望对大家理解OpenID Connect有所帮助。
最新回复 (0)