通用型認證與授權最小系統(tǒng),以較小的代價實現(xiàn)中立開源項目:UniAuth

年前,就如很多創(chuàng)業(yè)公司剛開始的時候一樣,點融網的主要業(yè)務架構在一個被稱為MainApp + Workflow上的應用:

MainApp處理投資者的投資、充值、提現(xiàn)等投資端的操作;

用Workflow來處理所有的進件、審批、放款、催收等貸款端的操作。

當業(yè)務體量并不大的時候,世界一切都顯得那么簡單。前面一個包含了MainApp + Workflow的應用,后面一個包羅萬象的數據庫。一切為了快速的迭代和發(fā)展!彼時那是一個 App + 一個 DB的時代。

斗轉星移,點融網漸漸從一個小荷才露尖尖角的小松鼠,發(fā)展成一個互金領域的映日荷花別樣紅的強力領軍人物之一。到這個階段,很多公司都會面臨業(yè)務的復雜度極具上升,需要通過分拆業(yè)務系統(tǒng)來承載更多的業(yè)務流量及復雜性。于是很自然的,前邊的應用,從1變成了N。點融的世界開始變得不是那么簡單。我們的工程師面對著N * App 的場景。每個應用都在做自己的權限控制模塊。因為,似乎每個應用的服務對象都不盡相同。有銷售、有運營、有技術支持、有財務審計等等。

所以,誰/何種角色,對于某些特征資源擁有怎樣的訪問權限?這是縈繞在很多點融工程師心中的一個問題。

新的突破:認證和授權功能- UniAuth

兩年前,幾位點融的工程師,被賦予了這樣的使命:以較小的代價實現(xiàn)中立的,脫離于特定業(yè)務場景的認證(authentication) 和授權(authorization) 功能 – UniAuth。

擺在這些工程師面前的有這樣一些問題:市場上是否有類似的系統(tǒng)可以被使用呢?

UniAuth 這種類型的系統(tǒng),在市場上叫做 IAM (Identity Access Management) 。UniAuth 既是以做輕量化的 IAM為目標。 這方面在美帝做得最好的公司叫做 okta(15年估值15億美金) , ?amazon 的 AWS 里面也有 IAM。

美國的公司,對于國內有墻,服務器不穩(wěn)定的可能性、對中國 support 不好 這些因素導致我們很難選擇美國的 IAM產品,并且這些服務,本身的資費對于一個處于成長期的公司而言太貴,同時對于互金類公司而言,對于數據/系統(tǒng)的安全性的考量,我們會更傾向于基于框架上的二次開發(fā)模式。縱觀當時市場上輕量級的IAM 系統(tǒng), 要么沒有開源滿足點融需求可用的、要么僅存在于精美的PPT當中。

基于成本的考量,當時的點融還沒有相應的預算投入到這些在業(yè)務價值中的優(yōu)先級較小的項目中?;诙ㄖ苹枨蟮目剂孔约汗咀鲆粋€,持續(xù)投入資源在 support 上形成優(yōu)勢。UniAuth 的目標:

1)兼容目前子系統(tǒng)的權限控制模型

子系統(tǒng)的權限模型可以適配轉換進入新系統(tǒng)的權限模型。

2)具有廣泛的第三方鑒權系統(tǒng)或協(xié)議的可接納性

需要廣泛的鑒權系統(tǒng)/協(xié)議的集成支持,包括但不限于:sso,oauth,ntlm/kerberos,openid,ldap/ms active directory,saml...因為說不清未來要集成什么東西。但有需要時可以通過配置,或以較小的代價接入。

3)具有良好擴展性

擴展性表現(xiàn)在認證和授權的各個階段和環(huán)節(jié),每個環(huán)節(jié)都有默認實現(xiàn),但可以提供途徑根據需要進行覆寫和干預。這通常發(fā)生在子系統(tǒng)認為框架提供的某個環(huán)節(jié)不爽的場景,比如我覺得公共登錄頁很丑,我要定制自己的登錄頁。

4)方便的組,角色,人員權限分配和控制

當新加入業(yè)務操作人員時,管理人員只需要簡短操作就可以方便的進行賬戶權限分配,控制,管理,權限開關設置等。

5)代碼侵入性

權限控制對系統(tǒng)業(yè)務級代碼無侵入性,或有較少侵入性。

6)使用成熟解決方案,不重復造輪子

使用業(yè)界久經考驗的成熟開源方案,少些代碼,遇到問題通過社區(qū)很快得到解決。

基于以上設計原則,我們選擇了 CAS + Spring Security 的開源組合來作為我們 Uniauth 框架開發(fā)的基礎、設計一套基于mysql的權限模型將其融入到 SpringSecurity 中,為點融網的前后端分離進行了定制化,Uniauth 雛形就有了。

架構設計

1)系統(tǒng)依賴架構圖


在這樣的架構下,cas 服務器獨立地存在,擁有了擴展 uniauth-server 數據源的可能性,可以同時 從 LDAP 取得企業(yè)用戶數據,也允許客戶端以純 webservice 的形式集成到 Uniauth 當中。在authentication、authorization、data level filter 的整個鏈條中,每一個鏈條都可以被打斷。

舉例來講,我們來了一個python base 的客戶,他只想要做 authentication,那么在上圖中,只需要通過 cas 完成 authentication拿到用戶的 identity,然后再使用 identity 去 uniauth-server 得到該 identity 的 profile即可滿足其需求,整個流程全部以 webservice 的形式完成, 與客戶端語言無關。

再舉例來講,數據系統(tǒng)想要數據,直接問 uniauth-server 的 API 索取即可。當然默認情況下我們提供了強大的基于 SpringSecurity 的 CAS 客戶端,內網 Java base 的客戶集成起來要相對容易很多。

2)項目內部的模塊依賴圖


源代碼模塊化,比如客戶端(uniauth-server的)如:業(yè)務系統(tǒng)、數據系統(tǒng)僅依賴 common 模塊即可訪問 uniauth-server 的讀接口,并且盡可能少的依賴 jar包??蛻舳?uniauth-server的) 如:techops、cas 僅依賴 share-rw 即可訪問 uniauth-server的讀和寫接口。同時 uniauth-server 提供的接口是基于 jax-rs 標準的 json 接口,所以異構系統(tǒng)完全可以自己寫客戶端訪問uniauth-server。

集成系統(tǒng)集成 Uniauth 框架圖:


該圖描述了一個以正常形式集成 Uniauth 系統(tǒng)的 java base 的集成方的流程。

(SSO 純 API 集成流程圖)

Uniauth 提供了純 API 的形式集成 Uniauth 的系統(tǒng),該方式給予了客戶最大化的自由,不想使用我們提供的任何 jar 包,或者異構系統(tǒng)。集成想要自由,就給它自由,而且自由的同時保證了認證機制的安全。

數據庫模型圖(在沒有加上 SaaS 化之前的版本):


現(xiàn)在的數據庫里面對于 User 表又擴展了其 EAV 模型,增加了 SaaS etc..幾個比較重要的點:

1.所有的實體數據都不會被刪除,只會被禁用(status 字段)

2.角色可以通過組賦予與集成、也可以直接賦予人

3.組樹狀結構的 closure table 設計

4.不同的 domain 擁有不同的 role 和 permission,權限數據在不同集成系統(tǒng)之間隔離,而 user 和 group 數據又是共享的

5.audit 表通過 aop, 記錄下對數據庫和 API 的一切訪問軌跡

6.樹狀數據庫設計

為了避免過長的篇幅描述 UniAuth 中多個樹狀數據結構,以一個網易評論樹來做講解:


UniAuth采取了閉包表的數據設計方式:


Comment Table Data:


Comment Path Table Data:


這種設計,comment table 本身并不保存評論與評論之間的關系,而將該關系用另外一張表(comment_path)保存起來,理論上講需要 O(n2)的空間來存儲關系,但現(xiàn)實中并不會需要這么多。


3)數據結構關系

每根紅線都是 comment_path 中的一條數據,線條上的數字為 depth。

1.查詢直接回復4號 comment 的 comment(父查子)

select c.* from comment c join comment_path cp on (c.id = cp.descendant) where cp.ancestor = 4 and depth = 1;

2.查詢所有回復4號的子 comment(父查所有子)

select c.* from comment c join comment_path cp on (c.id = cp.descendant) where cp.ancestor = 4;

如果你需要保留層級關系,則將 cp 中的值也返回即可

3.查詢所有7號的父 comment(子查所有父)

select c.* from comment c JOIN comment_path cp on (c.id = cp.ancestor) where cp.descendant = 7;

4.添加一條子回復到 6號 comment 上(新增)

step a:

insert into comment(value, topic_id, user_id) values('(10)我以gin食阼啦', 1, 2);

拿到該句返回的 id, 假設為10

step b:

insert into comment_path (ancestor, descendant, depth) select cp.ancestor, 10, cp.depth+1 from comment_path as cp where cp.descendant=6 union all select 10, 10, 0;

只要擁有子 comment_id 為6作為子節(jié)點的節(jié)點,全都新增一個 id 為10,depth+1的子節(jié)點 并且插入一個10, 10, 0的節(jié)點

5.從評論鏈中刪除4號 comment 及其子 comment(刪除子或者子樹)

delete a from comment_path a join comment_path b on (a.descendant = b.descendant) where b.ancestor=4;這句話等價于"delete from comment_path where descendant in (select descendant from comment_path where ancestor = 4);”

但 mysql 會報 from 句子中的表不能用于 update

6.將6號 comment 的父 comment 更改為2號(移動子或者子樹)

step a:

delete a from comment_path as a join comment_path as d on a.descendant = d.descendant left join comment_path as x on x.ancestor = d.ancestor and x.descendant = a.ancestor where d.ancestor = 6 and x.ancestor is null;

這樣刪除的原因和需求5一致

step b:

insert into comment_path (ancestor, descendant, depth) select supertree.ancestor, subtree.descendant, supertree.depth+subtree.depth+1 from comment_path as supertree join comment_path as subtree where subtree.ancestor = 6 and supertree.descendant = 2;

以上6種需求覆蓋了最為常用的幾種情況,解決了基本上 UniAuth 在閉包表上遇到的所有的問題。

closure table 是反模式設計的一種經典設計,在結構化數據庫里面,SQL 可以很輕易高效地支持對樹的各種各樣的增、刪、改、查、移的需求。這種設計給到 UniAuth 系統(tǒng)中的數據表設計特點給了很大的支持。

UniAuth 優(yōu)勢分析

1)成熟度

市場上會有一些開源的 IAM 系統(tǒng)。相較于很多項目在項目前期處于 bug 較多的探索時期,UniAuth 經過兩年多的點融內部研發(fā),和互金生產環(huán)境的檢驗,UniAuth 已經是一個成熟的生產環(huán)境質量的產品。

2)成本

相較于市場上一些 IAM 系統(tǒng)不菲的軟件授權費用/授權使用費用,UniAuth 將項目源碼完全開源。并鼓勵更多的極客可以貢獻的代碼,讓很多公共模塊可以投入更少,成效更快。

3)框架支持與拓展

UniAuth 的底層架構實現(xiàn)了 SpringSecurity,并且通過 CAS 實現(xiàn) Authentication,因此可以支持包括SPEL在內的所有 CAS,SpringSecurity 的特性及其拓展。

4)數據庫及設計

對于早期的創(chuàng)業(yè)公司而言,成本控制永遠是一個中心話題。基于 MySQL 的數據庫,降低了很大的運營成本。并且,UniAuth 的數據庫設計,對于樹狀結構數據的增改,做了大量優(yōu)化和特定設計。這會在后文提到。

5)客戶端支持/跨域訪問

同時支持客戶端和 REST API 訪問,解決跨域訪問問題。

6)SSO

CAS 天生自帶 SSO 的實現(xiàn),為應用的 Authentication 提供更多的擴展可能性。

UniAuth 開源

隨著點融的發(fā)展,點融技術部門也以更加開放的心態(tài)回饋社會,將UniAuth項目加入到開源項目社區(qū)。

點融開源社區(qū):https://github.com/dianrong/UniAuth

本文作者:錢晟龍 Arc_Qian(點融黑幫),現(xiàn)任點融網架構組產品研發(fā)工程師,主要任務是思考并嘗試解決各類點融網邁出第一公里之后遇到的現(xiàn)實問題。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 我們時常會遇到這樣的場景,如:組織結構圖、回復評論的評論鏈、用于組織資源的樹形資源組。 如圖: 而作為一名程序員如...
    點融黑幫閱讀 25,639評論 4 37
  • 世間萬物皆空。唯其空,便能包容萬物。昨晚,讀書分享會結束后,我在世界之窗轉車,在392公交車上,結識了來自英國的年...
    詹尼佛閱讀 249評論 1 1
  • 一個偶然的機會,去參加了一場讀書人的小聚會,正襟危坐之后,聽了幾個說書人分享了自己帶來的一些讀書感受,或是談家國戰(zhàn)...
    壹百度閱讀 349評論 1 2

友情鏈接更多精彩內容