項(xiàng)目經(jīng)驗(yàn)分享:在 JustAuth Plus 中添加 HTTP API 的登陸方式
本次分享來(lái)自 Just Auth 社區(qū)的余志海同學(xué)(在 JustAuth Plus 中添加 HTTP API 的登陸方式[1])的項(xiàng)目經(jīng)驗(yàn)。
項(xiàng)目綜述
什么是 JustAuth Plus(JAP),它有什么用?
JustAuth Plus 衍生于 JustAuth 項(xiàng)目。JustAuth 是一個(gè)第三方授權(quán)登錄的工具類庫(kù),它集成了國(guó)內(nèi)外多家知名的第三方平臺(tái)。JustAuth Plus 是在 JustAuth 的基礎(chǔ)上進(jìn)行開(kāi)發(fā)的,是一款開(kāi)源的登錄認(rèn)證中間件,基于模塊化設(shè)計(jì),為所有需要登錄認(rèn)證的 WEB 應(yīng)用提供一套標(biāo)準(zhǔn)的技術(shù)解決方案,開(kāi)發(fā)者可以基于 JAP 適配絕大多數(shù)的 WEB 系統(tǒng)(自有系統(tǒng)、聯(lián)邦協(xié)議),就像集成 JustAuth 一樣,簡(jiǎn)單方便。假如你想查看更多關(guān)于 JustAuth Plus 的信息可以點(diǎn)擊進(jìn)入其官網(wǎng):https://justauth.plus。
JustAuth Plus 目前支持多種認(rèn)證登陸方式,例如 Oauth2.0、OIDC、賬號(hào)密碼等方式,但是還不支持通過(guò) HTTP API 接口的形式進(jìn)行登陸驗(yàn)證。本次的項(xiàng)目需求就是為 JustAuth Plus 編寫 HTTP API 模塊。
需求分析
在 “以 HTTP API 接口形式進(jìn)行登陸驗(yàn)證的過(guò)程” 中,存在三個(gè)主體:
1.業(yè)務(wù)系統(tǒng)(開(kāi)發(fā)者系統(tǒng))2.第三方系統(tǒng)(身份服務(wù)提供商)3.用戶
用戶在登陸業(yè)務(wù)系統(tǒng)時(shí),會(huì)向業(yè)務(wù)系統(tǒng)提供用戶的認(rèn)證信息。業(yè)務(wù)系統(tǒng)通過(guò) HTTP API 接口向第三方系統(tǒng)發(fā)送認(rèn)證請(qǐng)求,以此來(lái)進(jìn)行用戶信息的認(rèn)證鑒權(quán)。示意圖如下:

對(duì)于開(kāi)發(fā)業(yè)務(wù)系統(tǒng)的開(kāi)發(fā)者而言,業(yè)務(wù)系統(tǒng)中可能需要集成多個(gè)第三方系統(tǒng),各個(gè)系統(tǒng)對(duì)外暴露的 HTTP API 的協(xié)議規(guī)范可能有所不同。因此在業(yè)務(wù)系統(tǒng)中集成第三方系統(tǒng)變?yōu)榱艘患值氖虑椤?/p>
在此次的項(xiàng)目開(kāi)發(fā)中,我需要做的就是添加 JAP 中 HTTP API 模塊,開(kāi)發(fā)者在簡(jiǎn)單配置該模塊之后就能很輕松地在其業(yè)務(wù)系統(tǒng)中集成第三方系統(tǒng)的登陸認(rèn)證功能。
模塊難點(diǎn)
在沒(méi)有使用本模塊的情況下,第三方系統(tǒng)向外暴露 HTTP API 接口,開(kāi)發(fā)者向其發(fā)送鑒權(quán)請(qǐng)求時(shí)需要遵守 HTTP 認(rèn)證鑒權(quán)協(xié)議。本模塊需要為開(kāi)發(fā)者屏蔽 HTTP 認(rèn)證鑒權(quán)協(xié)議上的細(xì)節(jié),這就是開(kāi)發(fā)本模塊的難點(diǎn)所在。
在查閱了許多資料文檔(參見(jiàn)文末參考文獻(xiàn)),深入學(xué)習(xí)了 HTTP 認(rèn)證鑒權(quán)之后,總結(jié)出了 HTTP 認(rèn)證的三大方式:
1、BASIC 認(rèn)證:

Basic 認(rèn)證是最簡(jiǎn)單的 HTTP 認(rèn)證鑒權(quán)方式,認(rèn)證過(guò)程簡(jiǎn)單明了,在認(rèn)證過(guò)程中會(huì)直接發(fā)送明文密碼,很容易導(dǎo)致密碼泄漏,適用于安全性要求不高的系統(tǒng)。

2、DIGEST 認(rèn)證

Digest 認(rèn)證是為了為彌補(bǔ) BASIC 認(rèn)證存在的弱點(diǎn),其用了一種nonce隨機(jī)數(shù)字符串,雙方約好對(duì)哪些信息進(jìn)行哈希運(yùn)算即可完成雙方身份的驗(yàn)證。但是,假如認(rèn)證報(bào)文被攻擊者攔截,攻擊者仍然可以獲取到受限資源,安全性還是不足。
3、BEARER 認(rèn)證

BEAER 認(rèn)證也可以稱之為 Bearer Token 認(rèn)證,我們經(jīng)常使用的 JWT 就是一種 Bearer Token 認(rèn)證方式。Token 是 Bearer 認(rèn)證的核心,服務(wù)端通過(guò)校驗(yàn) Token 合法性來(lái)進(jìn)行認(rèn)證授權(quán)。
第三方身份服務(wù)提供商向外暴露的 HTTP API 認(rèn)證接口一般就是以上三種認(rèn)證方式的其中之一。
模塊編碼
在解決了 HTTP 認(rèn)證鑒權(quán)協(xié)議這個(gè)難點(diǎn)之后,項(xiàng)目代碼編寫也就不那么復(fù)雜了。
該模塊的示意圖如下:

功能特性:
?多 HTTP 認(rèn)證協(xié)議支持:BASIC、DIGEST、BARER?支持開(kāi)發(fā)自定義添加請(qǐng)求頭?支持開(kāi)發(fā)者自定義添加請(qǐng)求參數(shù)?支持開(kāi)發(fā)者自定義認(rèn)證信息解析策略
代碼設(shè)計(jì):
?subject包:對(duì)于 Http 認(rèn)證鑒權(quán)中的請(qǐng)求頭或響應(yīng)頭?util包:該模塊需要使用到的工具類?HttpApiConfig:這個(gè)類是一個(gè)配置類,需要由開(kāi)發(fā)者配置?HttpApiStrategy:該模塊的核心類,向第三方身份服務(wù)提供商發(fā)起代理請(qǐng)求

開(kāi)發(fā)者在使用 HttpApi 模塊的時(shí)候需要提供 HttpApiConfig 配置,HttpApi 模塊會(huì)根據(jù)配置信息結(jié)合用戶認(rèn)證請(qǐng)求向第三方系統(tǒng)發(fā)起認(rèn)證請(qǐng)求。
在這里截取幾段 HttpApiStrategy 中的代碼,希望能幫你更好的理解 jap-http-api 模塊的代碼設(shè)計(jì):



DEMO 演示
因?yàn)槟壳斑€沒(méi)有將代碼合并到 JustAuth Plus 官方倉(cāng)庫(kù)[2],所以還不能直接引用新的 HttpApi 模塊。最終版本或許與當(dāng)前版本有差異,在這里只做演示。
運(yùn)行環(huán)境說(shuō)明:
?系統(tǒng):MacOS BigSur 11.4?編譯器:IntelliJ IDEA 2021.1.3?JDK:11.0.11(備注:JAP 項(xiàng)目本身是以 JDK 1.8 為基礎(chǔ)開(kāi)發(fā)的)?Maven:3.6.3
以下的代碼演示了開(kāi)發(fā)者如何在自己的業(yè)務(wù)系統(tǒng)中集成 jap-http-api 模塊。
1、導(dǎo)入 JAP Maven 依賴
<dependency><groupId>com.fujieid</groupId><artifactId>jap</artifactId><version>1.0.3</version><type>pom</type></dependency>
2、編寫測(cè)試 Controller
@GetMapping("/basic")public ResponseEntity authBasic(HttpServletRequest request, HttpServletResponse response ){HttpApiStrategy httpApiStrategy = new HttpApiStrategy(new JapHttpApiUserService(), new JapConfig());// 配置 HttpApi 模塊HttpApiConfig httpApiConfig = new HttpApiConfig()// 指定第三方 Http認(rèn)證類別.setAuthSchema(HttpApiConfig.AuthSchemaEnum.BASIC)// 指定第三方 Http認(rèn)證方式.setHttpMethod(HttpApiConfig.HttpMethodEnum.GET)// 指定用戶傳入認(rèn)證信息存放的位置.setAuthInfoField(HttpApiConfig.AuthInfoFieldEnum.BODY)// 指定第三方的登陸地址(我啟動(dòng)了一個(gè)本地服務(wù)當(dāng)作第三方系統(tǒng)).setLoginUrl("localhost:8088/api/v1/source1");// 將認(rèn)證信息交給 http-api 模塊,http-api 模塊負(fù)責(zé)代理驗(yàn)證JapResponse authenticate = httpApiStrategy.authenticate(httpApiConfig, request, response);// 獲得認(rèn)證結(jié)果if(authenticate.isSuccess()){return new ResponseEntity(200,"login success",authenticate.getData());}else{return new ResponseEntity(403,"login failure",authenticate.getData());}}
3、模擬用戶發(fā)送登陸請(qǐng)求,進(jìn)行測(cè)試

項(xiàng)目總結(jié)
首先,最最最重要的就是明確需求。最開(kāi)始接到項(xiàng)目的時(shí)候,我對(duì)項(xiàng)目需求的理解其實(shí)是產(chǎn)生了一些偏差的。我起初以為是實(shí)現(xiàn)一個(gè) RESTFul 風(fēng)格的完整的認(rèn)證鑒權(quán)框架,但是項(xiàng)目的實(shí)際需求和我理解的完全不同。在沒(méi)有透徹的理解需求的情況下就開(kāi)始了編碼工作,做了很多無(wú)用功,也浪費(fèi)了時(shí)間精力,我想這也是很多小伙伴在初次接觸項(xiàng)目開(kāi)發(fā)時(shí)常犯的錯(cuò)誤吧,哈哈。
其次,這個(gè)項(xiàng)目主要就是 Http 認(rèn)證鑒權(quán)協(xié)議的落地實(shí)現(xiàn),所以需要查閱很多權(quán)威資料,包括但不限于各種文獻(xiàn)、RFC文檔、百科,在此期間接觸到很多了新的名詞、概念。而且需要在理解需求之后將其轉(zhuǎn)化為編碼實(shí)現(xiàn)。
關(guān)于編碼方面,設(shè)計(jì)一個(gè)框架,需要考慮到框架的易用性、代碼的健壯性、代碼的規(guī)范性等,能夠做好這些,對(duì)編碼能力有很大的提升。在進(jìn)行編碼的過(guò)程中還需要做好規(guī)劃,那一部分代碼編寫優(yōu)先級(jí)最高,比如我在編碼開(kāi)始之前就進(jìn)行了規(guī)劃安排。

關(guān)于 JAP
JAP 是什么?
JAP 是一款開(kāi)源的登錄認(rèn)證中間件,基于模塊化設(shè)計(jì),為所有需要登錄認(rèn)證的 WEB 應(yīng)用提供一套標(biāo)準(zhǔn)的技術(shù)解決方案,開(kāi)發(fā)者可以基于 JAP 適配絕大多數(shù)的 WEB 系統(tǒng)(自有系統(tǒng)、聯(lián)邦協(xié)議)。
JAP 有哪些功能?

JAP 有什么優(yōu)勢(shì)?
?易用性:JAP 的 API 沿襲 JustAuth 的簡(jiǎn)單性,做到了開(kāi)箱即用的程度。JAP 高度抽象各種登錄場(chǎng)景,提供了多套簡(jiǎn)單使用的 API,極大程度的降低了開(kāi)發(fā)者的學(xué)習(xí)成本和使用成本?全面性:JAP 全量適配 JustAuth 支持的第三方平臺(tái),實(shí)現(xiàn)第三方登錄。同時(shí)也支持所有基于標(biāo)準(zhǔn)OAuth2.0 協(xié)議或者 OIDC 協(xié)議或者 SAML 協(xié)議的應(yīng)用、系統(tǒng),同時(shí) JAP 還提供不同語(yǔ)言版本的項(xiàng)目 SDK,適配多種研發(fā)場(chǎng)景?模塊化:JAP 基于模塊化設(shè)計(jì)開(kāi)發(fā),針對(duì)每一種登錄場(chǎng)景,比如賬號(hào)密碼、OAuth、OIDC等,都單獨(dú)提供了獨(dú)有的模塊化解決方案?標(biāo)準(zhǔn)化:JAP 和業(yè)務(wù)完全解耦,將登錄認(rèn)證相關(guān)的邏輯抽象出一套標(biāo)準(zhǔn)的技術(shù)解決方案,針對(duì)每一種業(yè)務(wù)場(chǎng)景,比如用戶登錄、驗(yàn)證密碼、創(chuàng)建并綁定第三方系統(tǒng)的賬號(hào)等,都提供了一套標(biāo)準(zhǔn)的策略或者接口,開(kāi)發(fā)者可以基于 JAP,靈活并方便的完成相關(guān)業(yè)務(wù)邏輯的開(kāi)發(fā)和適配?通用性:JAP 不僅可以用到第三方登錄、OAuth授權(quán)、OIDC認(rèn)證等業(yè)務(wù)場(chǎng)景,還能適配開(kāi)發(fā)者現(xiàn)有的業(yè)務(wù)系統(tǒng)的普通賬號(hào)密碼的登錄場(chǎng)景,基本將所有登錄相關(guān)的業(yè)務(wù)場(chǎng)景都已經(jīng)涵蓋。針對(duì) WEB 應(yīng)用,JAP 將提供滿足各種不同登錄場(chǎng)景的解決方案(和開(kāi)發(fā)語(yǔ)言無(wú)關(guān))
JAP 適用于哪些場(chǎng)景?
JAP 適用于所有需要登錄認(rèn)證功能的場(chǎng)景。比如:?要求規(guī)范:新項(xiàng)目立項(xiàng),你們需要研發(fā)一套包含登錄、認(rèn)證的系統(tǒng),并且從長(zhǎng)遠(yuǎn)方面考慮,你們需要一套標(biāo)準(zhǔn)的、靈活的、功能全面的登錄認(rèn)證功能。?需求靈活:現(xiàn)有登錄模塊為自研,但是新一輪的技術(shù)規(guī)劃中,你們想將登錄認(rèn)證模塊重構(gòu),以更加靈活的架構(gòu)適應(yīng)后面的新需求,比如:集成 MFA 登錄、集成 OAuth 登錄、SAML登錄等。?力求省事:你們的項(xiàng)目太多(或者是開(kāi)發(fā)語(yǔ)言較多,比如:Java、Python、Node 等),每個(gè)項(xiàng)目都需要登錄認(rèn)證模塊,想解決這種重復(fù)勞動(dòng)的問(wèn)題,使研發(fā)人員有更多的時(shí)間和精力投入到業(yè)務(wù)開(kāi)發(fā)中,提高研發(fā)產(chǎn)能和研發(fā)效率。關(guān)于 JAP 的更多內(nèi)容,可以參考《JAP 產(chǎn)品技術(shù)白皮書[3]》
相關(guān)鏈接
?Gitee:https://gitee.com/fujieid/jap?Github:https://github.com/fujieid/jap?CodeChina:https://codechina.csdn.net/fujieid/jap?開(kāi)發(fā)者文檔:https://justauth.plus
參考文獻(xiàn)
?RFC7617-The 'Basic' HTTP Authentication Scheme?RFC7235-Hypertext Transfer Protocol (HTTP/1.1): Authentication?RFC7519-JSON Web Token (JWT)?RFC2069-An Extension to HTTP : Digest Access Authentication?HTTP 身份驗(yàn)證 - HTTP | MDN (mozilla.org)?Other authentication methods - GitHub Docs?HTTP摘要認(rèn)證 - 維基百科,自由的百科全書 (wikipedia.org)
引用鏈接
[1] **在 JustAuth Plus 中添加 HTTP API 的登陸方式**: https://summer.iscas.ac.cn/#/org/prodetail/210860602[2] JustAuth Plus 官方倉(cāng)庫(kù): https://gitee.com/fujieid/jap[3] JAP 產(chǎn)品技術(shù)白皮書: https://justauth.plus/paper/JAP-paper-V1.0.0.pdf
