點融網(wǎng)開源權(quán)限控制框架Uniauth簡介

Uniauth是一個基于CAS和Spring Security開源產(chǎn)品而開發(fā)的權(quán)限控制框架,它的目標(biāo)是服務(wù)于點融網(wǎng)內(nèi)部的各個子系統(tǒng)涨岁,只要集成了該框架拐袜,就能以很小的代價實現(xiàn)認(rèn)證和授權(quán)功能。而權(quán)限設(shè)計是開發(fā)系統(tǒng)中不可規(guī)避的一個環(huán)節(jié)梢薪。

為什么要做權(quán)限控制框架

每個公司內(nèi)部都有大量的子系統(tǒng)蹬铺,點融網(wǎng)也不例外。

這些子系統(tǒng)有為普通員工服務(wù)的秉撇,比如各種OA系統(tǒng)甜攀;有為專門業(yè)務(wù)操作人員服務(wù)的,比如電銷系統(tǒng)琐馆,庫存管理系統(tǒng)规阀;也有為技術(shù)人員服務(wù)的,比如我們常見的git啡捶,confluence姥敛,jira等系統(tǒng)。

很多時候瞎暑,這些子系統(tǒng)都有各自獨立的賬戶體系和權(quán)限控制方式彤敛。當(dāng)有新員工入職時,需要在各個必須的子系統(tǒng)中為其開設(shè)帳號并受以權(quán)限了赌,浪費了大量的人力物力墨榄。而且,各個子系統(tǒng)權(quán)限控制的模式參差不齊勿她,權(quán)限控制的數(shù)據(jù)模型也不盡相同袄秩,很多時候都留有安全隱患。比如,使用Fiddler等工具攔截http報文后之剧,修改一些參數(shù)便可以訪問到本不該被訪問到的隱私內(nèi)容郭卫。

另外,作為使用這些子系統(tǒng)的員工也比較痛苦背稼,因為他們有可能在這些子系統(tǒng)中設(shè)置不同的密碼贰军,密碼記憶混亂甚至忘記密碼也常有發(fā)生。

如果這些子系統(tǒng)可以集成一套成熟的權(quán)限控制框架蟹肘,使用唯一的一套賬戶體系词疼,能夠完成統(tǒng)一登錄和登出(Single?Sign?On/Off),甚至各個子系統(tǒng)的管理員可以自行分配屬于自己系統(tǒng)的組帘腹、角色贰盗、權(quán)限等信息,將會是一件大快人心的事阳欲!

綜上所述舵盈,您可能認(rèn)為我們確實應(yīng)該設(shè)計一套權(quán)限控制的框架來幫我們來做這件事。在設(shè)計這套框架之前胸完,讓我們來看看需要做權(quán)限控制的一些常見業(yè)務(wù)場景书释。

需要權(quán)限控制的常見業(yè)務(wù)場景

頁面級別(視圖層)

控制菜單展現(xiàn),按鈕顯示赊窥,數(shù)據(jù)渲染

方法訪問控制

方法和類,事前和事后狸页,aop切點語法支持

數(shù)據(jù)過濾

同樣一份數(shù)據(jù)锨能,對不同的人而言看到的數(shù)量或?qū)傩圆煌?/p>

請求的URL的攔截

只有屬于某些/個角色的登錄用戶才可以訪問某些模式的URL

某些方法調(diào)用需要將入?yún)⒑彤?dāng)前用戶相關(guān)聯(lián)的情況

比如對于密碼修改方法,登錄人員的只能修改自己賬戶的密碼

更細(xì)粒度的控制

使用ACL對域?qū)ο笾贫ǜ?xì)粒度的權(quán)限訪問策略

其他更多種的訪問控制策略的引入

比如基于IP(支持CIDR表示)芍耘,基于訪問時間段址遇,remember?me功能等等

可以看到,做到盡善盡美的權(quán)限控制十分不易斋竞,如果自己去實現(xiàn)所有這些業(yè)務(wù)場景的控制將花費大量力氣倔约,而且也不一定能做好。

那究竟該如何這個設(shè)計權(quán)限控制框架坝初,或者說它的設(shè)計原則又是什么呢浸剩?

Uniauth的設(shè)計原則

我們認(rèn)為,Uniauth的設(shè)計原則應(yīng)該體現(xiàn)在以下方面:

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

子系統(tǒng)的權(quán)限模型可以適配轉(zhuǎn)換進(jìn)入新系統(tǒng)的權(quán)限模型鳄袍。

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

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

具有良好擴(kuò)展性

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

方便的組簿寂,角色漾抬,人員權(quán)限分配和控制

當(dāng)新加入業(yè)務(wù)操作人員時,管理人員只需要簡短操作就可以方便的進(jìn)行賬戶權(quán)限分配常遂,控制纳令,管理,權(quán)限開關(guān)設(shè)置等克胳,

代碼侵入性

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

使用成熟解決方案漠另,不重復(fù)造輪子

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

基于以上設(shè)計原則性湿,我們選擇了CAS?+?Spring?Security的開源組合來作為我們Uniauth框架開發(fā)的基礎(chǔ)。

Uniauth簡介

Uniauth是一個基于CAS和Spring?Security開源產(chǎn)品而開發(fā)的權(quán)限控制框架满败,其中統(tǒng)一認(rèn)證功能由CAS提供肤频,當(dāng)訪問多個集成了Uniauth框架的業(yè)務(wù)子系統(tǒng)時,只要用戶登錄一次算墨,便可以訪問所有其他業(yè)務(wù)子系統(tǒng)(SSO功能)宵荒;授權(quán)功能由Spring?Security提供,所有Spring?Security的功能都可以使用净嘀。

同時我們對Spring?Security的某些常用關(guān)鍵功能進(jìn)行了封裝和再增強报咳,以便使您更專注于權(quán)限控制的業(yè)務(wù)實現(xiàn)(比如通過注解,表達(dá)式或JSP?Security?Tag)而無需了解Spring?Security的底層配置和機(jī)制面粮。所以少孝,Uniauth框架基于Spring?Security,而又不僅僅是一個Spring?Security熬苍。

事實上稍走,我們提供的是一個定制版的Spring?Security框架袁翁,更好用,更強大婿脸,這主要體現(xiàn)在以下幾點:

1粱胜、無縫集成CAS實現(xiàn)SSO

在集成Uniauth框架后,用戶訪問本業(yè)務(wù)系統(tǒng)狐树,一旦檢測到用戶未登陸焙压,會被自動引導(dǎo)到CAS統(tǒng)一登錄頁,完成登錄后再跳轉(zhuǎn)到業(yè)務(wù)系統(tǒng)抑钟,業(yè)務(wù)系統(tǒng)可以自動獲取該用戶的基本屬性涯曲,如用戶名,域信息在塔,角色信息等(還可對屬性進(jìn)行擴(kuò)展幻件,見下文)。同時蛔溃,無需再登陸即可訪問其他集成的業(yè)務(wù)子系統(tǒng)绰沥。

2、對XML和數(shù)據(jù)庫兩方定義的URL攔截數(shù)據(jù)進(jìn)行合并

在普通情況下使用Spring?Security贺待,對URL攔截的定義位于其配置文件的標(biāo)簽下的中徽曲,如:

如果進(jìn)行定制的話麸塞,常規(guī)做法是實現(xiàn)FilterInvocationSecurityMetadataSource接口秃臣,用于加載預(yù)定義在數(shù)據(jù)庫中的intercept-url定義,以便用于運行時權(quán)限判斷哪工。

但上面兩種情況通常是互斥的甜刻,這是因為配置文件中的定義由Spring?Security框架在啟動時加載,并且注入到一個FilterSecurityInterceptor實例中正勒;來自數(shù)據(jù)庫定義的MetadataSource會被注入到另外的一個自定義FilterSecurityInterceptor實例中。在運行時權(quán)限判斷中傻铣,兩個FilterSecurityInterceptor無論誰先執(zhí)行誰后執(zhí)行章贞,都會在基于Role的判斷中影響或覆蓋另外一個。

在Uniauth中會自動對這兩邊定義的intercept-url進(jìn)行合并非洲,并注入到同一個FilterSecurityInterceptor實例中鸭限,所有intercept-url定義都會起作用。

3两踏、在URL定義中尋找最優(yōu)匹配請求路徑的條目

在權(quán)限控制的開始階段败京,我們通常會做出粗糙控制,比如規(guī)定只有登陸用戶才能訪問本業(yè)務(wù)系統(tǒng):

隨著業(yè)務(wù)的不斷精細(xì)化梦染,我們可能會定義各種不同匹配模式(基于ant或正則)赡麦,如只有ROLE_ADMIN角色才能訪問/admin開始的url:

在普通的Spring?Security使用中朴皆,這兩個定義的先后順序很重要,因為它會自上而下進(jìn)行掃描泛粹,一旦發(fā)現(xiàn)有一條路徑匹配就會選用遂铡。

這樣就會產(chǎn)生問題,比如一個普通用戶(ROLE_USER)晶姊,訪問了/admin/update/info這個url扒接,因為第一條定義表明只要是認(rèn)證過的用戶就可以訪問所有形式的url,這樣就造成了普通用戶也可以訪問管理員才可以訪問的頁面们衙。

在Uniauth中不會產(chǎn)生這個問題钾怔,Uniauth會把來自配置文件或數(shù)據(jù)庫中的所有匹配請求路徑的url定義聚集起來,然后從中選擇一個最匹配(最長匹配)的進(jìn)行選用蒙挑,無論url定義的順序是什么宗侦。

對應(yīng)于上面的例子,/admin/update/info這個請求路徑對于兩個url定義都匹配脆荷,但是顯然更匹配第二個凝垛,所以會選用第二個定義。但第二個要求是ROLE_ADMIN角色才能訪問蜓谋,用戶本身是ROLE_USER梦皮,所以會拒絕他的請求。

我們建議對所有需要保護(hù)的資源url進(jìn)行定義切分桃焕,因為不被保護(hù)的url資源屬于公用資源剑肯,誰都可以訪問。

4观堂、添加hasPermission表達(dá)式支持

我們在Uniauth中添加了對hasPermission表達(dá)式的支持让网,hasPermission表達(dá)式是最精細(xì)的港令,最徹底的權(quán)限控制方式骏掀,用于判斷當(dāng)前登陸用戶對于某個業(yè)務(wù)對象是否有某種訪問權(quán)限沪哺。

在Uniauth中隐轩,您只要實現(xiàn)UniauthPermissionEvaluator接口炭臭,或者從UniauthPermissionEvaluatorImpl擴(kuò)展奶镶,根據(jù)自己的需要覆寫兩個hasPermission方法或其中一個即可羹奉,hasPermission表達(dá)式可以內(nèi)嵌在@PreAuthorize注解中鲫尊,或者也可以使用在JSP安全標(biāo)簽中笔横。

5竞滓、對用戶登錄session進(jìn)行并發(fā)控制

為了安全考慮,我們配置了并發(fā)Session訪問控制吹缔,即Concurrent?Session?Control商佑。當(dāng)同一個賬戶在不同的Session會話中訪問同一個業(yè)務(wù)系統(tǒng)時,第二個Session會將第一個Session會話踢出厢塘,如果用戶在第一個Session會話中繼續(xù)活動茶没,會被提示“對不起肌幽,您的會話超時,或者您的賬號在另外一個窗口中已登錄礁叔,導(dǎo)致本次會話結(jié)束牍颈,如有需要,請重新登錄琅关!”煮岁,引導(dǎo)用戶登陸或徹底退出登錄系統(tǒng)。

6涣易、對UserDetails對象隨需進(jìn)行擴(kuò)展

UserDetails在Spring?Security中是一個很重要的對象画机,它代表了通過認(rèn)證后的用戶實體,即principal對象新症。

我們通常使用principal對象在@PreAuthorize中結(jié)合SpEL(Spring?Expression?Language)進(jìn)行基本的權(quán)限控制步氏,看看當(dāng)前用戶實體是否有權(quán)限進(jìn)行某個方法的調(diào)用,這是權(quán)限控制中很重要的一個環(huán)節(jié)徒爹。比如對如下方法控制:

@PreAuthorize("hasRole('ROLE_SUPER_ADMIN')?and?principal.permMap['DOMAIN']?!=?null?and?principal.permMap['DOMAIN'].contains('techops')")

public?Response?resetPassword(@RequestBody?UserParam?userParam)?{?...?}

從UserDetails中可以獲取到跟當(dāng)前登錄用戶相關(guān)聯(lián)的屬性荚醒,比如用戶名,密碼隆嗅,賬戶是否被鎖定界阁,密碼是否過期,用戶被授予的角色列表等基本信息胖喳。

在Uniauth框架中對UserDetails進(jìn)行了基本擴(kuò)充泡躯,除包含上述用戶信息外,我們還添加了當(dāng)前用戶登錄的域信息丽焊,用戶在該域上的權(quán)限(privilege)信息等较剃。

另外,每個子系統(tǒng)可能有不同業(yè)務(wù)需要技健,我們添加了UserInfoCallBack回調(diào)接口写穴,只要業(yè)務(wù)系統(tǒng)實現(xiàn)了它,就能在UserDetails中添加自己需要的擴(kuò)展用戶屬性雌贱,比如該用戶所有的組列表信息确垫,或者跟自己業(yè)務(wù)系統(tǒng)相關(guān)的其他用戶屬性信息等。

在大部分情況下帽芽,添加擴(kuò)展屬性的目的是用于上面介紹的@PreAuthorize表達(dá)式判斷,或者用于自身業(yè)務(wù)操作的其他目的翔冀。

Uniauth框架和子系統(tǒng)的集成框架圖

Uniauth系統(tǒng)已經(jīng)上線导街,歡迎有集成需求的系統(tǒng)跟我們聯(lián)系,我們將竭誠提供集成支撐服務(wù)纤子。

本文作者:許增偉(David Xu)搬瑰,現(xiàn)任點融網(wǎng)成都團(tuán)隊架構(gòu)組開發(fā)工程師款票,主要開發(fā)與業(yè)務(wù)無關(guān)的橫切系統(tǒng)和組件,如權(quán)限控制系統(tǒng)泽论,消息組件艾少,日志組件和一些公共管理工具等等。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末翼悴,一起剝皮案震驚了整個濱河市缚够,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌鹦赎,老刑警劉巖谍椅,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異古话,居然都是意外死亡雏吭,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進(jìn)店門陪踩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來杖们,“玉大人,你說我怎么就攤上這事肩狂≌辏” “怎么了?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵婚温,是天一觀的道長描焰。 經(jīng)常有香客問我,道長栅螟,這世上最難降的妖魔是什么荆秦? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮力图,結(jié)果婚禮上步绸,老公的妹妹穿的比我還像新娘。我一直安慰自己吃媒,他們只是感情好瓤介,可當(dāng)我...
    茶點故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著赘那,像睡著了一般刑桑。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上募舟,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天祠斧,我揣著相機(jī)與錄音,去河邊找鬼拱礁。 笑死琢锋,一個胖子當(dāng)著我的面吹牛辕漂,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播吴超,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼钉嘹,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了鲸阻?” 一聲冷哼從身側(cè)響起跋涣,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎赘娄,沒想到半個月后仆潮,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡遣臼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年性置,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片揍堰。...
    茶點故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡鹏浅,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出屏歹,到底是詐尸還是另有隱情隐砸,我是刑警寧澤,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布蝙眶,位于F島的核電站季希,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏幽纷。R本人自食惡果不足惜式塌,卻給世界環(huán)境...
    茶點故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望友浸。 院中可真熱鬧峰尝,春花似錦、人聲如沸收恢。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽伦意。三九已至火窒,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間驮肉,已是汗流浹背沛鸵。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人曲掰。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像奈辰,于是被迫代替她去往敵國和親栏妖。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,465評論 2 348

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,737評論 25 707
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理奖恰,服務(wù)發(fā)現(xiàn)吊趾,斷路器,智...
    卡卡羅2017閱讀 134,628評論 18 139
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫瑟啃、插件论泛、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,059評論 4 62
  • 【約拿書2: 9】但我必用感謝的聲音獻(xiàn)祭與你。我所許的愿, 我必償還蛹屿。救恩出于耶和華屁奏。 親愛的弟兄姐妹們,我們每天...
    高橋先生閱讀 426評論 0 0
  • 借考察調(diào)研的時機(jī)错负,再次來到了美麗的杭州坟瓢,因平時有跑步的習(xí)慣,跑西湖的沖動立馬涌上心頭…… 肇慶...
    高洪昭閱讀 481評論 0 0