單點登陸(Single Sign On),簡稱爲SSO,是目前比較流行的企業業務整合的解決方案之一。
SSO的定義是在多個應用系統中,用戶只須要登陸一次就能夠訪問全部相互信任的應用系統。javascript
若是你不瞭解用戶池、單點登陸和認證受權,建議先閱讀基礎概念。html
npm install http-server -g
)若是你尚未帳號,請點擊這裏註冊 Authing 帳號,註冊完成後請進入控制檯並建立一個用戶池。java
第三方登陸 -> OIDC 應用選項卡,點擊藍色的「建立 OIDC 應用」按鈕。git
填上你的應用名,指定此 OIDC 應用的二級域名(認證地址),回調地址,其餘參數保留默認便可。點擊「肯定」。 github
參數解釋web
認證地址,一個 authing.cn 的二級域名,用戶將在此網址進行登陸。算法
回調 URL,OIDC 登陸成功後,回調到開發者本身業務的地址。本教程爲演示,填寫的地址是 http://localhost:8080,實際場景下要填寫本身的業務地址。npm
在應用列表中點擊剛建立好的應用,記錄下 AppID,二級域名,供之後使用。json
本教程只是爲了演示,所以咱們沒選擇高級框架,這可讓咱們專一於 Authing 自己。瀏覽器
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <title>Authing SSO Example</title> </head> <body></body> </html>
增長三個按鈕控件到 body 中,目的是爲了演示如何使用 SDK 管理單點登陸狀態。
<button id="btn-login">login</button> <button id="btn-track-session">trackSession</button> <button id="btn-logout">logout</button>
從 CDN 加載 AuthingSSO 的 SDK。填入你的 OIDC 應用 ID 和 域名,進行初始化。
<script src="https://cdn.jsdelivr.net/npm/@authing/sso/dist/AuthingSSO.umd.min.js"></script> <script> let auth = new AuthingSSO({ appId: "YOUR_OIDC_APP_ID", appType: "oidc", appDomain: "OIDC_APP_DOMAIN.authing.cn" }); </script>
達到的效果是:
let login = document.getElementById("btn-login"); let trackSession = document.getElementById("btn-track-session"); let logout = document.getElementById("btn-logout"); login.onclick = function() { auth.login(); }; trackSession.onclick = async function() { let res = await auth.trackSession(); alert(JSON.stringify(res)); }; logout.onclick = async function() { let res = await auth.logout(); alert(JSON.stringify(res)); };
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <title>Authing SSO Example</title> </head> <body> <button id="btn-login">login</button> <button id="btn-track-session">trackSession</button> <button id="btn-logout">logout</button> <script src="https://cdn.jsdelivr.net/npm/@authing/sso/dist/AuthingSSO.umd.min.js"></script> <script> let auth = new AuthingSSO({ appId: "YOUR_OIDC_APP_ID", appType: "oidc", appDomain: "OIDC_APP_DOMAIN.authing.cn" }); let login = document.getElementById("btn-login"); let trackSession = document.getElementById("btn-track-session"); let logout = document.getElementById("btn-logout"); login.onclick = function() { auth.login(); }; trackSession.onclick = async function() { let res = await auth.trackSession(); alert(JSON.stringify(res)); }; logout.onclick = async function() { let res = await auth.logout(); alert(JSON.stringify(res)); }; </script> </body> </html>
示例代碼可從 Github 上找到,建議將 Github 上的代碼下載運行。
在終端中運行如下命令
$ git clone https://github.com/Authing/authing-sso-demo $ cd authing-sso-demo $ npm install -g http-server $ http-server
以後在瀏覽器訪問 http://localhost:8080。
{% hint style="warning" %}
若是本地 8080 端口已被佔用,應用可能會運行在 808一、8082 等後續端口。
{% endhint %}
最初,咱們沒有登陸,所以,點擊 trackSession 按鈕獲取到的登陸狀態爲空。
如今咱們點擊 login 按鈕,會跳轉到 OIDC 應用的用戶認證頁面,輸入用戶名密碼進行登陸。
瀏覽器被重定向到咱們以前設置的回調連接,記下 code 參數,用於後面換取用戶信息。
點擊 trackSession 按鈕,此時可以獲取到該用戶的登陸狀態,包括用戶 ID,應用 ID,應用類型。
點擊 logout 按鈕,輸出單點登出成功。
此時咱們再點擊 trackSession 按鈕,可見登陸狀態爲空,說明用戶已經單點登出了。
向如下地址發送 POST 請求:
POST https://OIDC_APP_DOMAIN.authing.cn/oauth/oidc/token
body 參數
參數名 | 意義 |
---|---|
client_id | OIDC 應用的 app_id |
redirect_uri | 在控制檯配置的 OIDC 回調 url 其中的一個值 |
scope | 須要請求的權限,若是須要獲取 email 和手機號須要有 phone email,若是須要 refresh_token 須要包含 offline_access 參考 scope 表格 |
response_type | OIDC 模式,能夠爲 code, id_token, id_token token, code id_token, code token, code id_token token 參考 OIDC 規範 |
prompt | 能夠爲 none,login,consent 或 select_account,指定 AP 與 End-User 的交互方式,如需 refresh_token,必須爲 consent 參考 OIDC 規範 |
state | 一個隨機字符串,用於防範 CSRF 攻擊,若是 response 中的 state 值和發送請求以前設置的 state 值不一樣,說明受到攻擊 |
nonce | 一個隨機字符串,用於防範 Replay 攻擊 |
返回示例
{ "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6InIxTGtiQm8zOTI1UmIyWkZGckt5VTNNVmV4OVQyODE3S3gwdmJpNmlfS2MifQ.eyJqdGkiOiJ4R01uczd5cmNFckxiakNRVW9US1MiLCJzdWIiOiI1YzlmNzVjN2NjZjg3YjA1YTkyMWU5YjAiLCJpc3MiOiJodHRwczovL2F1dGhpbmcuY24iLCJpYXQiOjE1NTQ1Mzc4NjksImV4cCI6MTU1NDU0MTQ2OSwic2NvcGUiOiJvcGVuaWQgcHJvZmlsZSBvZmZsaW5lX2FjY2VzcyBwaG9uZSBlbWFpbCIsImF1ZCI6IjVjYTc2NWUzOTMxOTRkNTg5MWRiMTkyNyJ9.wX05OAgYuXeYM7zCxhrkvTO_taqxrCTG_L2ImDmQjMml6E3GXjYA9EFK0NfWquUI2mdSMAqohX-ndffN0fa5cChdcMJEm3XS9tt6-_zzhoOojK-q9MHF7huZg4O1587xhSofxs-KS7BeYxEHKn_10tAkjEIo9QtYUE7zD7JXwGUsvfMMjOqEVW6KuY3ZOmIq_ncKlB4jvbdrduxy1pbky_kvzHWlE9El_N5qveQXyuvNZVMSIEpw8_y5iSxPxKfrVwGY7hBaF40Oph-d2PO7AzKvxEVMamzLvMGBMaRAP_WttBPAUSqTU5uMXwMafryhGdIcQVsDPcGNgMX6E1jzLA", "expires_in": 3600, "id_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6InIxTGtiQm8zOTI1UmIyWkZGckt5VTNNVmV4OVQyODE3S3gwdmJpNmlfS2MifQ.eyJzdWIiOiI1YzlmNzVjN2NjZjg3YjA1YTkyMWU5YjAiLCJub25jZSI6IjIyMTIxIiwiYXRfaGFzaCI6Ik5kbW9iZVBZOEFFaWQ2T216MzIyOXciLCJzaWQiOiI1ODM2NzllNC1lYWM5LTRjNDEtOGQxMS1jZWFkMmE5OWQzZWIiLCJhdWQiOiI1Y2E3NjVlMzkzMTk0ZDU4OTFkYjE5MjciLCJleHAiOjE1NTQ1NDE0NjksImlhdCI6MTU1NDUzNzg2OSwiaXNzIjoiaHR0cHM6Ly9hdXRoaW5nLmNuIn0.IQi5FRHO756e_eAmdAs3OnFMU7QuP-XtrbwCZC1gJntevYJTltEg1CLkG7eVhdi_g5MJV1c0pNZ_xHmwS0R-E4lAXcc1QveYKptnMroKpBWs5mXwoOiqbrjKEmLMaPgRzCOdLiSdoZuQNw_z-gVhFiMNxI055TyFJdXTNtExt1O3KmwqanPNUi6XyW43bUl29v_kAvKgiOB28f3I0fB4EsiZjxp1uxHQBaDeBMSPaRVWQJcIjAJ9JLgkaDt1j7HZ2a1daWZ4HPzifDuDfi6_Ob1ZL40tWEC7xdxHlCEWJ4pUIsDjvScdQsez9aV_xMwumw3X4tgUIxFOCNVEvr73Fg", "refresh_token": "WPsGJbvpBjqXz6IJIr1UHKyrdVF", "scope": "openid profile offline_access phone email", "token_type": "Bearer" }
OIDC 默認使用 OIDC 應用的 secret 對 token 進行驗證(也就是在建立應用時默認選擇 HS256 算法)。 若是你使用 javascript 那麼可使用 jsonwebtoken 進行驗證:
const jwt = require('jsonwebtoken'); let decoded = jwt.verify(token, <appSecret>);
若是是其餘語言,那麼你在服務端須要用 app_secret 做爲 HS256 簽名參數來計算簽名和 JWT 中的簽名進行對比,僞代碼以下:
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), "1133fd20c14e4cc29b6ecb71fb8eb952"// app_secret )
若是是 RS256 等非對稱加密算法,須要使用公鑰驗證簽名。Authing 將使用私鑰進行簽名,請使用 Authing 的公鑰來驗證簽名:
-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxRijj2seoesv5K0Z+ymR K7DSDPxdsM2sGQD2ZVhLjLsxZWJtXUXh7ERdUU6OT3BqYZZf7CLIhN6yyNtTOgfg pLG9HVJd7ZSKzuy2dS7mo8jD8YRtptAJmNFqw6z8tQp5MNG1ZHqp9isKqJmx/CFY kRdXBmjjj8PMVSP757pkC3jCq7fsi0drSSg4lIxrSsGzL0++Ra9Du71Qe/ODQKU0 brxaI1OKILtfcVPTHTaheV+0dw4eYkSDtyaLBG3jqsQbdncNg8PCEWchNzdO6aaj Uq4wbOzy/Ctp399mz0SGKfuC5S8gqAFABFT3DH3UD21ZztQZwFEV2AlvF+bcGEst cwIDAQAB -----END PUBLIC KEY-----
開發者在本身的服務中可使用 access_token 換取用戶信息。根據 scope 的不一樣,這裏的返回信息也會有所不一樣,字段符合 OIDC 規範,字段解釋請參考用戶信息字段含義。 請求連接:
GET https://users.authing.cn/oauth/oidc/user/userinfo?access_token=<access_token>
返回示例:
{ "sub": "<用戶在 Authing 的惟一標識>", "nickname": "Authing", "name": "張三", "locale": "en-US" }
更多字段解釋請參考用戶信息字段含義。
瞭解 OIDC 協議:
控制檯是你管理全部 Authing 資源的地方,瞭解 Authing 控制檯各模塊包含的內容和你能夠在控制檯中作的事情:
瞭解 Authing 提供的多種部署模型,以幫助你選擇該以怎樣的形式部署 Authing:
Authing 提供專業的身份認證和受權服務。
咱們爲開發者和企業提供用以保證應用程序安全所需的認證模塊,這讓開發人員無需成爲安全專家。
你能夠將任意平臺的應用接入到 Authing(不管是新開發的應用仍是老應用均可以),同時你還能夠自定義應用程序的登陸方式(如:郵箱/密碼、短信/驗證碼、掃碼登陸等)。
你能夠根據你使用的技術,來選擇咱們的 SDK 或調用相關 API 來接入你的應用。當用戶發起受權請求時,Authing 會幫助你認證他們的身份和返回必要的用戶信息到你的應用中。
<div align=center>Authing 在應用交互中的位置</div>