SSO的通用标准OpenID Connect
文章目錄
- 簡(jiǎn)介
- OpenID Connect是什么
- ID Token
- 請(qǐng)求ID Token
- ID Token可以做什么
- Open Connect認(rèn)證碼授權(quán)的例子
- User Info
簡(jiǎn)介
OpenID Connect簡(jiǎn)稱為OIDC,已成為Internet上單點(diǎn)登錄和身份管理的通用標(biāo)準(zhǔn)。 它在OAuth2上構(gòu)建了一個(gè)身份層,是一個(gè)基于OAuth2協(xié)議的身份認(rèn)證標(biāo)準(zhǔn)協(xié)議。
OAuth2實(shí)際上只做了授權(quán),而OpenID Connect在授權(quán)的基礎(chǔ)上又加上了認(rèn)證。
OIDC的優(yōu)點(diǎn)是:簡(jiǎn)單的基于JSON的身份令牌(JWT),并且完全兼容OAuth2協(xié)議。
今天我們將會(huì)介紹一下OIDC的具體原理。
OpenID Connect是什么
OpenID Connect發(fā)布于2014年,是建立在OAuth 2.0協(xié)議之上的簡(jiǎn)單身份層,它允許客戶端基于授權(quán)服務(wù)器或身份提供商(IdP)進(jìn)行的身份驗(yàn)證來(lái)驗(yàn)證最終用戶的身份,并獲得用戶的相關(guān)信息。
OpenID Connect提供了RESTful HTTP API,并使用Json作為數(shù)據(jù)的傳遞格式。
之前我們講到了基于XML格式的SAML協(xié)議,而OpenID Connect因?yàn)槠涓雍?jiǎn)潔的數(shù)據(jù)交換格式,被越來(lái)越多的應(yīng)用使用,已經(jīng)成為事實(shí)上的標(biāo)準(zhǔn)。
我們看一下OpenID connect的基本流程:
RP(client)發(fā)送一個(gè)認(rèn)證請(qǐng)求到 OpenID Provider(OP)。
OP對(duì)End User進(jìn)行認(rèn)證并獲得相應(yīng)的授權(quán)。
OP返回一個(gè)ID Token或者access Token給RP。
RP使用access token向UserInfo Endpoint請(qǐng)求用戶信息。
UserInfo Endpoint返回相應(yīng)的用戶信息給RP。
ID Token
ID Token就像是一個(gè)用戶的身份證,它是以JWT格式存在的,并且由OP進(jìn)行簽名,保證它的安全性。
獲取ID Token的方式就是向OP發(fā)送認(rèn)證請(qǐng)求。
因?yàn)镮D Token是以JWT格式存在的,JWT可以分為三個(gè)部分,分別是Header,Payload和Signature。
這里我們主要關(guān)注一下Payload的json內(nèi)容:
{"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的唯一標(biāo)識(shí);最長(zhǎng)為255個(gè)ASCII個(gè)字符;
- iss = Issuer Identifier:必須。提供認(rèn)證信息者的唯一標(biāo)識(shí)。一般是Url的host+path部分;
- aud = Audience(s):必須。標(biāo)識(shí)ID-Token的受眾。必須包含OAuth2的client_id;
- nonce:RP發(fā)送請(qǐng)求的時(shí)候提供的隨機(jī)字符串,用來(lái)減緩重放攻擊,也可以來(lái)關(guān)聯(lián)ID-Token和RP本身的Session信息。
- auth_time = AuthenticationTime:EU完成認(rèn)證的時(shí)間。如果RP發(fā)送認(rèn)證請(qǐng)求的時(shí)候攜帶max_age的參數(shù),則此Claim是必須的。
- acr = Authentication Context Class Reference:可選。表示一個(gè)認(rèn)證上下文引用值,可以用來(lái)標(biāo)識(shí)認(rèn)證上下文類。
- iat = Issued At Time:必須。JWT的構(gòu)建的時(shí)間。
- exp = Expiration time:必須。ID-Token的過(guò)期時(shí)間;
上面的是ID Token的標(biāo)準(zhǔn)Claims。
請(qǐng)求ID Token
現(xiàn)在我們知道了ID Token是什么,那么在OpenID Connect的RP客戶端如何請(qǐng)求一個(gè)ID Token呢?
雖然OpenID Connect并未指定應(yīng)如何實(shí)際驗(yàn)證用戶身份,這取決于提供者來(lái)決定。但是我們通常由Web瀏覽器來(lái)執(zhí)行認(rèn)證步驟。
瀏覽器將用戶重定向到認(rèn)證服務(wù)器的認(rèn)證窗口,用戶輸入用戶名和密碼之后,通過(guò)OAuth 2.0協(xié)議請(qǐng)求ID token。
使用OAuth 2.0來(lái)獲取ID Token有3種方式:
Authorization Code流程的步驟如下:
客戶端準(zhǔn)備身份認(rèn)證請(qǐng)求,請(qǐng)求里包含所需要的參數(shù)
客戶端發(fā)送請(qǐng)求到授權(quán)服務(wù)器
授權(quán)服務(wù)器對(duì)最紅用戶進(jìn)行身份認(rèn)證
授權(quán)服務(wù)得最終用戶的統(tǒng)一/授權(quán)
授權(quán)服務(wù)器把最終用戶發(fā)送回客戶端,同時(shí)帶著授權(quán)碼
客戶端使用授權(quán)碼向Token端點(diǎn)請(qǐng)求一個(gè)響應(yīng)
客戶端接收到響應(yīng),響應(yīng)的Body里面包含在和ID Token和Access Token
客戶端驗(yàn)證ID Token,并獲得用戶的一些身份信息
上圖就是一個(gè)隱式授權(quán)的例子,和Authorization Code模式不同的是,認(rèn)證服務(wù)器返回的是一個(gè)access token片段,只有這個(gè)片段,我們是無(wú)法得到access token的。
這里我們需要額外請(qǐng)求一次client resource服務(wù)器,服務(wù)器將會(huì)返回一個(gè)script腳本,通過(guò)這個(gè)腳本,我們對(duì)access token片段進(jìn)行解析,得到最終的access token。
混合模式比較少用到,它是前面兩種模式的混合,它允許從前端和后端分別獲取token值。
ID Token可以做什么
那么我們拿到請(qǐng)求得到的ID Token可以做什么事情呢?
服務(wù)器端不需要存儲(chǔ)會(huì)話信息,我們只需要在服務(wù)器端對(duì)token進(jìn)行驗(yàn)證即可。
可以將token傳遞給第三方,因?yàn)閠oken本身并不是敏感信息,所以我們可以將token傳遞給其他應(yīng)用程序或者后端服務(wù)。
令牌交互,我們可以通過(guò)ID Token去IdP服務(wù)器中請(qǐng)求access token,從而起到了交互token的目的。
Open Connect認(rèn)證碼授權(quán)的例子
這里我們舉一個(gè)使用認(rèn)證碼授權(quán)獲取到ID token的例子。
下面是一個(gè)重定向的例子:
HTTP/1.1 302 Found Location: 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:因?yàn)槲覀兪钦J(rèn)證碼模式,這里選擇code
-
scope:openid表示請(qǐng)求的是openid。
-
client_id:RP的client id,OP通過(guò)這個(gè)client_id來(lái)識(shí)別是否是可識(shí)別的RP。可以提前注冊(cè)或者提前約定。
-
state:RP生成的一個(gè)狀態(tài)標(biāo)準(zhǔn),主要為了防止攻擊。
-
redirect_uri:認(rèn)證完畢之后,跳轉(zhuǎn)的鏈接。
在OP端,將會(huì)檢測(cè)是否已經(jīng)存在一個(gè)有效的用戶session,否則將會(huì)彈出用戶登錄界面,讓用戶登錄。
登錄成功之后,client將會(huì)重定向到redirect_uri,并帶上認(rèn)證碼:
HTTP/1.1 302 Found Location: https://client.flydean.com/cb?code=SplxlOBeZQQYbYS6WxSbIA&state=af0ifjsldkj上面返回的code只是一個(gè)中間產(chǎn)物,RP需要將code提交給OP換取ID token。
這次我們直接使用一個(gè)后端的POST請(qǐng)求:
POST /token HTTP/1.1 Host: openid.flydean.com Content-Type: application/x-www-form-urlencoded Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JWgrant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA&redirect_uri=https%3A%2F%2Fclient.flydean.com%2Fcb- grant_type:authorization_code表示是授權(quán)碼格式
- code就是上面一步獲得的code
- redirect_uri是callback url
如果成功,OP會(huì)返回一個(gè)JSON對(duì)象,帶有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.ewogImlzcyI6ICJodHRwOi8vc2VydmVyLmV4YW1wbGUuY29tIiwKICJzdWIiOiAiMjQ4Mjg5NzYxMDAxIiwKICJhdWQiOiAiczZCaGRSa3F0MyIsCiAibm9uY2UiOiAibi0wUzZfV3pBMk1qIiwKICJleHAiOiAxMzExMjgxOTcwLAogImlhdCI6IDEzMTEyODA5NzAKfQ.ggW8hZ1EuVLuxNuuIJKX_V8a_OMXzR0EHR9R6jgdqrOOF4daGU96Sr_P6qJp6IcmD3HP99Obi1PRs-cwh3LO-p146waJ8IhehcwL7F09JdijmBqkvPeB2T9CJNqeGpe-gccMg4vfKjkM8FcGvnzZUN4_KSP0aAp1tOJ1zZwgjxqGByKHiOtX7TpdQyHE5lcMiKPXfEIQILVq0pc_E2DzL7emopWoaoZTF_m0_N0YzFC6g6EJbOEoRoSK5hoDalrcvRYLSrQAZZKflyuVCyixEoV9GfNQC3_osjzw2PAithfubEEBLuVVk4XUVrWOLrLl0nx7RkKU8NXNHq-rvKMzqg""access_token": "SlAV32hkKG","token_type": "Bearer","expires_in": 3600, }其中ID token的格式是JWT。
User Info
我們獲取到的ID token里面已經(jīng)包含了一些非常有用的claims信息。
事實(shí)上ID Token還可以包含其他的user info信息:
比如name,profile,picture,email,gender,birthdate,phone_number,address等等有用的信息。
我們可以在token請(qǐng)求的時(shí)候添加上額外的scope:
HTTP/1.1 302 Found Location: 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將會(huì)在token中加入email選項(xiàng)。
比如:
{"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/
本文來(lái)源:flydean的博客
歡迎關(guān)注我的公眾號(hào):「程序那些事」最通俗的解讀,最深刻的干貨,最簡(jiǎn)潔的教程,眾多你不知道的小技巧等你來(lái)發(fā)現(xiàn)!
總結(jié)
以上是生活随笔為你收集整理的SSO的通用标准OpenID Connect的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 安全声明标记语言SAML2.0初探
- 下一篇: 在wildfly中使用SAML协议连接k