專案經驗分享:在 JustAuth Plus 中新增 HTTP API 的登陸方式

七彩狼丿發表於2021-08-04

本次分享來自 Just Auth 社群的餘志海同學(在 JustAuth Plus 中新增 HTTP API 的登陸方式)的專案經驗。

專案綜述

什麼是 JustAuth Plus(JAP),它有什麼用?

JustAuth Plus 衍生於 JustAuth 專案。JustAuth 是一個第三方授權登入的工具類庫,它整合了國內外多家知名的第三方平臺。JustAuth Plus 是在 JustAuth 的基礎上進行開發的,是一款開源的登入認證中介軟體,基於模組化設計,為所有需要登入認證的 WEB 應用提供一套標準的技術解決方案,開發者可以基於 JAP 適配絕大多數的 WEB 系統(自有系統、聯邦協議),就像整合 JustAuth 一樣,簡單方便。假如你想檢視更多關於 JustAuth Plus 的資訊可以點選進入其官網:justauth.plus

JustAuth Plus 目前支援多種認證登陸方式,例如 Oauth2.0、OIDC、賬號密碼等方式,但是還不支援通過 HTTP API 介面的形式進行登陸驗證。本次的專案需求就是為 JustAuth Plus 編寫 HTTP API 模組。

需求分析

在 “以 HTTP API 介面形式進行登陸驗證的過程” 中,存在三個主體:

  1. 業務系統(開發者系統)
  2. 第三方系統(身份服務提供商)
  3. 使用者

使用者在登陸業務系統時,會向業務系統提供使用者的認證資訊。業務系統通過 HTTP API 介面向第三方系統傳送認證請求,以此來進行使用者資訊的認證鑑權。示意圖如下:

對於開發業務系統的開發者而言,業務系統中可能需要整合多個第三方系統,各個系統對外暴露的 HTTP API 的協議規範可能有所不同。因此在業務系統中整合第三方系統變為了一件棘手的事情。

在此次的專案開發中,我需要做的就是新增 JAP 中 HTTP API 模組,開發者在簡單配置該模組之後就能很輕鬆地在其業務系統中整合第三方系統的登陸認證功能。

模組難點

在沒有使用本模組的情況下,第三方系統向外暴露 HTTP API 介面,開發者向其傳送鑑權請求時需要遵守 HTTP 認證鑑權協議。本模組需要為開發者遮蔽 HTTP 認證鑑權協議上的細節,這就是開發本模組的難點所在。

在查閱了許多資料文件(參見文末參考文獻),深入學習了 HTTP 認證鑑權之後,總結出了 HTTP 認證的三大方式:

1、BASIC 認證:

Basic 認證是最簡單的 HTTP 認證鑑權方式,認證過程簡單明瞭,在認證過程中會直接傳送明文密碼,很容易導致密碼洩漏,適用於安全性要求不高的系統。

2、DIGEST 認證

Digest 認證是為了為彌補 BASIC 認證存在的弱點,其用了一種nonce隨機數字符串,雙方約好對哪些資訊進行雜湊運算即可完成雙方身份的驗證。但是,假如認證報文被攻擊者攔截,攻擊者任然可以獲取到受限資源,安全性還是不足。

3、BEARER 認證

BEAER 認證也可以稱之為 Bearer Token 認證,我們經常使用的 JWT 就是一種 Bearer Token 認證方式。Token 是 Bearer 認證的核心,服務端通過校驗 Token 合法性來進行認證授權。

第三方身份服務提供商向外暴露的 HTTP API 認證介面一般就是以上三種認證方式的其中之一。

模組編碼

在解決了 HTTP 認證鑑權協議這個難點之後,專案程式碼編寫也就不那麼複雜了。

該模組的示意圖如下:

功能特性:

  • 多 HTTP 認證協議支援:BASIC、DIGEST、BARER
  • 支援開發自定義新增請求頭
  • 支援開發者自定義新增請求引數
  • 支援開發者自定義認證資訊解析策略

程式碼設計:

  • subject包:對於 Http 認證鑑權中的請求頭或響應頭
  • util包:該模組需要使用到的工具類
  • HttpApiConfig:這個類是一個配置類,需要由開發者配置
  • HttpApiStrategy:該模組的核心類,向第三方身份服務提供商發起代理請求

開發者在使用 HttpApi 模組的時候需要提供 HttpApiConfig 配置,HttpApi 模組會根據配置資訊結合使用者認證請求向第三方系統發起認證請求。

在這裡擷取幾段 HttpApiStrategy 中的程式碼,希望能幫你更好的理解 jap-http-api 模組的程式碼設計:

DEMO 演示

因為目前還沒有將程式碼合併到 JustAuth Plus 官方倉庫,所以還不能直接引用新的 HttpApi 模組。 最終版本或許與當前版本有差異,在這裡只做演示。

執行環境說明:

  • 系統:MacOS BigSur 11.4
  • 編譯器:IntelliJ IDEA 2021.1.3
  • JDK:11.0.11(備註:JAP 專案本身是以 JDK 1.8 為基礎開發的)
  • Maven:3.6.3

以下的程式碼演示了開發者如何在自己的業務系統中整合 jap-http-api 模組。

1、匯入 JAP Maven 依賴

<dependency>
    <groupId>com.fujieid</groupId>
    <artifactId>jap</artifactId>
    <version>1.0.3</version>
    <type>pom</type>
</dependency>
複製程式碼

2、編寫測試 Controller

@GetMapping("/basic")
public ResponseEntity authBasic(HttpServletRequest request, HttpServletResponse response ){
    HttpApiStrategy httpApiStrategy = new HttpApiStrategy(new JapHttpApiUserService(), new JapConfig());
    // 配置 HttpApi 模組
    HttpApiConfig httpApiConfig = new HttpApiConfig()
            // 指定第三方 Http認證類別
            .setAuthSchema(HttpApiConfig.AuthSchemaEnum.BASIC)
            // 指定第三方 Http認證方式
            .setHttpMethod(HttpApiConfig.HttpMethodEnum.GET)
            // 指定使用者傳入認證資訊存放的位置
            .setAuthInfoField(HttpApiConfig.AuthInfoFieldEnum.BODY)
             // 指定第三方的登陸地址(我啟動了一個本地服務當作第三方系統)
            .setLoginUrl("localhost:8088/api/v1/source1");

    // 將認證資訊交給 http-api 模組,http-api 模組負責代理驗證
    JapResponse authenticate = httpApiStrategy.authenticate(httpApiConfig, request, response);
    // 獲得認證結果
    if(authenticate.isSuccess()){
        return new ResponseEntity(200,"login success",authenticate.getData());
    }else{
        return new ResponseEntity(403,"login failure",authenticate.getData());
    }
}
複製程式碼

3、模擬使用者傳送登陸請求,進行測試

專案總結

首先,最最最重要的就是明確需求。最開始接到專案的時候,我對專案需求的理解其實是產生了一些偏差的。我起初以為是實現一個 RESTFul 風格的完整的認證鑑權框架,但是專案的實際需求和我理解的完全不同。在沒有透徹的理解需求的情況下就開始了編碼工作,做了很多無用功,也浪費了時間精力,我想這也是很多小夥伴在初次接觸專案開發時常犯的錯誤吧,哈哈。

其次,這個專案主要就是 Http 認證鑑權協議的落地實現,所以需要查閱很多權威資料,包括但不限於各種文獻、RFC文件、百科,在此期間接觸到很多了新的名詞、概念。而且需要在理解需求之後將其轉化為編碼實現。

關於編碼方面,設計一個框架,需要考慮到框架的易用性、程式碼的健壯性、程式碼的規範性等,能夠做好這些,對編碼能力有很大的提升。在進行編碼的過程中還需要做好規劃,那一部分程式碼編寫優先順序最高,比如我在編碼開始之前就進行了規劃安排。

關於 JAP

JAP 是什麼?

JAP 是一款開源的登入認證中介軟體,基於模組化設計,為所有需要登入認證的 WEB 應用提供一套標準的技術解決方案,開發者可以基於 JAP 適配絕大多數的 WEB 系統(自有系統、聯邦協議)。

JAP 有哪些功能?

JAP 開源的統一登入認證標準元件 - 包含的功能

JAP 有什麼優勢?

  • 易用性:JAP 的 API 沿襲 JustAuth 的簡單性,做到了開箱即用的程度。JAP 高度抽象各種登入場景,提供了多套簡單使用的 API,極大程度的降低了開發者的學習成本和使用成本
  • 全面性:JAP 全量適配 JustAuth 支援的第三方平臺,實現第三方登入。同時也支援所有基於標準OAuth2.0 協議或者 OIDC 協議或者 SAML 協議的應用、系統,同時 JAP 還提供不同語言版本的專案 SDK,適配多種研發場景
  • 模組化:JAP 基於模組化設計開發,針對每一種登入場景,比如賬號密碼、OAuth、OIDC等,都單獨提供了獨有的模組化解決方案
  • 標準化:JAP 和業務完全解耦,將登入認證相關的邏輯抽象出一套標準的技術解決方案,針對每一種業務場景,比如使用者登入、驗證密碼、建立並繫結第三方系統的賬號等,都提供了一套標準的策略或者介面,開發者可以基於 JAP,靈活並方便的完成相關業務邏輯的開發和適配
  • 通用性:JAP 不僅可以用到第三方登入、OAuth授權、OIDC認證等業務場景,還能適配開發者現有的業務系統的普通賬號密碼的登入場景,基本將所有登入相關的業務場景都已經涵蓋。針對 WEB 應用,JAP 將提供滿足各種不同登入場景的解決方案(和開發語言無關)

JAP 適用於哪些場景?

JAP 適用於所有需要登入認證功能的場景。比如:

  • 要求規範:新專案立項,你們需要研發一套包含登入、認證的系統,並且從長遠方面考慮,你們需要一套標準的、靈活的、功能全面的登入認證功能。
  • 需求靈活:現有登入模組為自研,但是新一輪的技術規劃中,你們想將登入認證模組重構,以更加靈活的架構適應後面的新需求,比如:整合 MFA 登入、整合 OAuth 登入、SAML登入等。
  • 力求省事:你們的專案太多(或者是開發語言較多,比如:Java、Python、Node 等),每個專案都需要登入認證模組,想解決這種重複勞動的問題,使研發人員有更多的時間和精力投入到業務開發中,提高研發產能和研發效率。

關於 JAP 的更多內容,可以參考《JAP 產品技術白皮書

相關連結

參考文獻

  • 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 身份驗證 - HTTP | MDN (mozilla.org)
  • Other authentication methods - GitHub Docs
  • HTTP摘要認證 - 維基百科,自由的百科全書 (wikipedia.org)

相關文章