如何基于Python建設企業認證和權限控制平臺
原創【51CTO.com原創稿件】企業內網,建立在企業內部,為員工提供信息的共享和交流,為業務提供運營和管理的支撐,已是當今企業信息化建設必不可少的一個項目。隨著企業的規模越來越大,業務越來越廣,系統建設就顯得尤為重要。
統一認證系統是企業內網系統建設的基礎,主要實現用戶管理、身份認證、權限管理和單點登錄等功能,以解決企業內網系統建設過程中用戶定義模糊、用戶身份組織零亂、交叉權限管理和應用系統出口多樣性等棘手的問題。
基于此,五阿哥運維技術團隊基于Python建設了統一認證(BUC:Back User Center)和權限控制(ACL:Access Control List)平臺,這個系統技術架構圖如下:
一、 系統的功能
1.用戶管理
在企業中,每個用戶都有一個唯一的賬號進行登錄,用戶的賬號和個人身份信息(包含姓名、郵件等公共屬性)會集中保存在內網統一認證系統里。但對于同一個用戶在外部系統中的賬號,如微信、釘釘、Tower等第三方系統,統一認證系統也可以通過定時同步或實時查詢等方式獲取到用戶的信息。
2.安全管理
對于保存在企業內網中的用戶賬號進行認證是比較方便的,對于保存在外部系統中的用戶賬號,可以通過定時同步或實時驗證等方式來驗證用戶的鑒權,最終統一以唯一的身份使用戶登錄進入系統。
同時,企業內部存在多個不同的業務應用,以所有應用均接入統一認證平臺為基礎,各個業務系統的用戶認證采用單點登錄認證模式,一次登錄即可在各個業務子系統中完成自動認證并獲得相關授權。
3.應用管理
不同的業務系統會對用戶進行不同的角色劃分,不同的角色又會劃分出細粒度的權限。角色權限在統一認證系統中保存,在一個地方就可以完成用戶授權信息的設定。
4.系統接入
支持各種技術棧的系統接入,包含Java和Python等,其中各技術棧的SDK可以在Github項目中找到。
5.三方應用
第三方應用,包含郵箱,VPN,無線等直接進行SSO登錄。
6.系統監控
對系統運行、操作、會話進行監控,保障在受到外部或者內部攻擊時,能夠及時發現,進行實例回溯。
7.系統審計
對平臺所有操作進行審計,在出現系統權限錯亂或者安全問題的時候,對平臺操作進行審計。
二、 系統架構設計
1.接口設計
企業內網的統一認證平臺建議基于B/S模式設計,后端使用Django框架以快速開發,用DB+LDAP方式完成用戶各類信息的存儲,保障存儲和查詢效率。 統一認證的核心問題是鑒權中心和各子系統之間的通信接口問題,用戶認證接口協議可以基于標準化HTTP/HTTPS方式實現,并對外提供不同語言的SDK(如Python CAS庫、Java Web過濾器等),使得第三方業務系統的接入不完全依賴于特定的開發環境。
2.安全設計
對于接入系統,認證中心接口協議調用采用HTTPS傳輸的方式,通信安全問題將轉化到HTTPS傳輸的安全性問題上,而對于HTTPS通道的攻擊,可以由單獨的網絡掃描模塊專門負責監控。
對于統一認證和SSO接口參數的信息安全,一方面網站可采用專有加密算法對參數內容進行加密,另一方面,可以采用IP認證策略來保證對接口雙方的信任,系統通過通道安全和信息加密雙保險的措施來保證統一認證體系的接口安全。
同時系統配有全方面的應用監控和訪問日志的審計,當機器發生異常情況或日志審計檢測到有可疑入侵行為時,會自動以多種方式通知到運維工程師和相關負責人。
三、 BUC使用技術和實現
1.用戶管理
通常在企業中,每個用戶擁有一個唯一的身份標識,即用戶名。同時用戶在其他內網或外部應用也存在著對應的用戶,如果能使用同一個用戶身份最為方便;獨立的用戶可以通過關聯不同的系統的用戶使之對外呈現為一個用戶。用戶可以在不同的應用系統中使用,這一切的基礎是有一個中央的系統來保存和管理這些用戶。常見的解決方案有Windows活動目錄和LDAP。
(1)Windows活動目錄域服務
使用 Active Directory(R) 域服務 (AD DS) 服務器角色,可以創建用于用戶和資源管理的可伸縮、安全及可管理的基礎機構,并可以提供對啟用目錄的應用程序(如 Microsoft(R) Exchange Server)的支持。
圖-1:AD的功能,來自微軟的介紹
AD DS 提供了一個分布式數據庫,該數據庫可以存儲和管理有關網絡資源的信息,以及啟用了目錄的應用程序中特定于應用程序的數據。 運行 AD DS 的服務器稱為域控制器。 管理員可以使用 AD DS 將網絡元素(如用戶、計算機和其他設備)整理到層次內嵌結構。內嵌層次結構包括 Active Directory 林、林中的域以及每個域中的組織單位 (OU)。
域模式的最大好處就是單一的網絡登錄能力,用戶只要在域中有一個賬戶,就可以在整個網絡中漫游。活動目錄服務增強了信任關系,擴展了域目錄樹的靈活性。活動目錄把一個域作為一個完整的目錄,域之間能夠通過一種基于Kerberos認證的可傳遞的信任關系建立起樹狀連接,從而使單一賬戶在該樹狀結構中的任何地方都有效,這樣在網絡管理和擴展時就比較輕松。
同時,活動目錄服務把域又詳細劃分成組織單元。組織單元是一個邏輯單元,它是域中一些用戶和組、文件與打印機等資源對象的集合。組織單元中還可以再劃分下級組織單元,下級組織單元能夠繼承父單元的訪問許可權。每一個組織單元可以有自己單獨的管理員并指定其管理權限,它們都管理著不同的任務,從而實現了對資源和用戶的分級管理。活動目錄服務通過這種域內的組織單元樹和域之間的可傳遞信任樹來組織其信任對象,為動態活動目錄的管理和擴展帶來了極大的方便。
(2)LDAP技術
輕型目錄存取協定(英文:Lightweight Directory Access Protocol,縮寫:LDAP)是一個開放的,中立的,工業標準的應用協議,通過IP協議提供訪問控制和維護分布式信息的目錄信息。
目錄服務在開發內部網和與互聯網程序共享用戶、系統、網絡、服務和應用的過程中占據了重要地位。例如,目錄服務可能提供了組織有序的記錄集合,通常有層級結構,例如公司電子郵件目錄。同理,也可以提供包含了地址和電話號碼的電話簿。
圖-2:LDAP目錄樹圖示,來自網絡
LDAP協議是跨平臺的和標準的協議,因此應用程序就不用為LDAP目錄放在什么樣的服務器上操心了。實際上,LDAP得到了業界的廣泛認可,因為它是Internet的標準。廠商都很愿意在產品中加入對LDAP的支持,因為他們根本不用考慮另一端(客戶端或服務端)是怎么樣的。
LDAP服務器可以是任何一個開放源代碼或商用的LDAP目錄服務器(或者還可能是具有LDAP界面的關系型數據庫),因為可以用同樣的協議、客戶端連接軟件包和查詢命令與LDAP服務器進行交互。
與LDAP不同的是,如果軟件廠商想在軟件產品中集成對DBMS的支持,那么通常都要對每一個數據庫服務器單獨定制。不像很多商用的關系型數據庫,你不必為LDAP的每一個客戶端連接或許可協議付費。大多數的LDAP服務器安裝起來很簡單,也容易維護和優化。
(3)用戶管理實踐
根據國內企業辦公網絡的實際情況,用戶計算機通常為Windows系統,通通接入到Windows活動目錄中進行管理。而且Windows活動目錄兼容LDAP協議,我們使用活動目錄作為統一保存用戶信息的中央系統,再通過LDAP協議使用程序訪問域控制器將用戶信息同步到統一認證服務器中。
圖-3:企業內部系統基本結構
由上圖架構所示,一方面常見的辦公系統(如代碼倉庫、Wiki等)自身即支持LDAP認證,通過配置Windows AD中的目錄/用戶搜索規則即完成對登錄用戶的認證;另一方面自行開發的業務系統通過中央認證服務器提供的接口間接的對Windows AD進行登錄用戶的認證,即一個用戶,一套密碼,在多個系統中都可使用。
- # auth.py
- class ActiveDirectoryAuthenticationBackEnd:
- def authenticate(self, username, password, request=None):
- if not username or not password:
- return None
- try:
- # 建立同域控的連接
- server = Server(settings.AD_SERVER_NAME, use_ssl=True)
- # 驗證用戶使用的用戶名和密碼
- conn = Connection(server, "%s\\%s" % (settings.AD_DOMAIN, username), password, auto_bind=True, authentication=NTLM)
- # 認證通過,返回系統中注冊的用戶,不存在則創建
- user = conn.bound and self.get_or_create_user(username, conn) or None
- return user
- except LDAPBindError:
- return None
- def get_or_create_user(self, username, conn=None):
- try:
- user = User.objects.get(username=username)
- except User.DoesNotExist:
- if conn is None:
- return None
- # 從域控向中央認證系統中同步注冊一個新用戶
- if conn.search(USER_BASE_DN, "(sAMAccountName=%s)" % username, SUBTREE, attributes=["sn", "givenName"]):
- result = conn.response[0]["attributes"]
- user = User(username=username)
- user.first_name = result["givenName"]
- user.last_name = result["sn"]
- user.email = "%s@%s" % (username, settings.AD_EMAIL_HOST)
- user.save()
- else:
- return None
- return user
2.身份認證
(1)通過外部應用認證
外部應用,如即時通訊軟件釘釘等,這些應用存有單獨的一套用戶憑證,通過應用提供的免登服務,將應用中的用戶與統一認證服務器中的用戶進行一一對應,當用戶在外部應用中登錄后,自動獲得在企業內應用的已登錄狀態。
(2)通過TOTP動態驗證碼認證
OTP (One-Time Password) ,一次性密碼,也稱動態口令。它是使用密碼技術實現在客戶端和服務器之間共享秘密的一種認證技術,是一種強認證技術,是增強目前靜態口令認證的一種非常方便的技術手段,是一種重要的雙因素認證技術。
TOTP (Time-base One-Time Password) ,基于時間的一次性密碼,也稱時間同步的動態密碼。當在一些用戶不方便輸入密碼或者忘記密碼的場景中,我們可以使用TOTP進行認證。服務器和用戶各自保管共同的密鑰,通過比對基于時間分片與哈希計算出的動態數字驗證碼即可完成對用戶身份的認證。主流實現為Google Authenticator(Google身份驗證器),阿里的身份寶也兼容該算法。
圖-4:TOTP算法圖示
(3)雙因子認證
雙因子認證(Two-Factor Authentication)是指結合密碼以及實物(信用卡、SMS手機、令牌或指紋等生物標志)兩種元素對用戶進行認證的方法。
圖-5:動態驗證碼流程圖示
結合上面使用的TOTP驗證碼,對于安全級別較高的應用或資源路徑、或是系統探測到風險較高的操作時,即可以對用戶重定向至雙因子認證頁面,進一步保障系統安全。
3.單點登錄
主要實現方式:
(1)共享 cookie
利用同一域名下的cookie共享為基礎,將session id寫入共享cookie,在實現了后臺session共享存儲和訪問后,不同的應用之間即實現了單點登錄。
(2)Broker-based (基于經紀人)
在一個基于經紀人的 SSO 解決方案中,有一個集中的認證和用戶帳號管理的服務器。經紀人能被用于進一步請求的電子的身份存取。中央數據庫的使用減少了管理的代價,并為認證提供一個公共和獨立的"第三方"。例如 Kerberos 、 Sesame 、 IBM KryptoKnight (憑證庫思想 ) 等。
(3)Agent-based(基于代理人)
在這種解決方案中,有一個自動地為不同的應用程序認證用戶身份的代理程序。這個代理程序需要設計有不同的功能。比如,它可以使用口令表或加密密鑰來自動地將認證的負擔從用戶移開。代理人被放在服務器上面,在服務器的認證系統和客戶端認證方法之間充當一個 " 翻譯 " ,例如 SSH 等。
(4)Token-based
口令認證,比如 FTP 、郵件服務器的登錄認證,這是一種簡單易用的方式,實現一個口令在多種應用當中使用。
- 基于網關
- 基于 SAML
- Ticket-based(基于票據)
4.BUC實踐
在我們的內網應用中,最終選擇了CAS協議作為單點登錄的方案。CAS(Central Authentication Service)是 Yale 大學發起的一個企業級的、開源的項目,旨在為 Web 應用系統提供一種可靠的單點登錄解決方法。CAS開始于2001年,并在2004年12月正式成為JA-SIG的一個項目。
CAS的主要特點有:
- 開源
- 支持多種認證機制:Active Directory、JAAS、JDBC、LDAP、X.509等
- 安全策略:使用票據(Ticket)來實現支持的認證協議
- 支持授權:可以決定哪些服務可以請求和驗證服務票據
- 提供高可用性
- 支持多種客戶端及SDK: Java, .Net,PHP,Python,nodejs 等
- 服務端也有多種語言實現
(1)登錄驗證流程
圖-6:用戶、CAS客戶端、服務端三方交互過程
- # urls.py
- # 在配置文件中將/cas 路徑掛載至根路徑,即可通過/cas/login來訪問中央認證頁面,后臺的認證過程會通過已有的認證服務進行
- urlpatterns = [
- ……
- url(r"^cas/", include("mama_cas.urls", namespace="cas")),
- ……
- ]
(2)安全擴展
當CAS服務端完成了對用戶和CAS客戶端的驗證之后,CAS服務端將驗證后的用戶信息傳輸給CAS客戶端(目標應用),同時也可根據配置返回該應用下的附屬用戶信息,如用戶擁有的該應用下的角色、權限和屬性。目標應用根據服務器返回的用戶信息進一步檢查用戶可訪問的資源,適當的展示業務視圖。
- # settings.py
- MAMA_CAS_SERVICES = [
- {
- 'SERVICE': '.*',
- 'CALLBACKS': [
- 'base.cas_callbacks.user_profile_attributes',
- 'security.cas_callbacks.user_security_attributes',
- # 按需加入回調函數
- ]
- }
- ]
- # user_profile_attributes
- # 返回用戶的基本信息
- def user_profile_attributes(user, service):
- return {
- “username”: get_username(user),
- “name”: get_display_name(user)
- }
- # user_security_attributes.py
- # 返回用戶在該業務/服務中擁有的角色、權限和訪問路徑信息
- def user_security_attributes.py(user, service):
- return {
- “roles”: get_roles(service, user),
- “permissions”: get_permissions(service, user),
- “urls”: get_urls(service, user)
- }
四、ACL使用技術和實現
在現代企業,尤其是互聯網企業中,產品業務繁多,對數據安全、訪問控制都提出了很高的要求,基于用戶組織結構、匯報線等傳統的分組模式已經無法適應和滿足多變的互聯網扁平化管理模式的需要,因此我們選擇了基于角色和權限的動態分組來設計和實現企業中不用應用可以共享的安全訪問管理系統。
1.權限
權限是針對資源和操作層面的最小安全訪問控制單元,例如:
- 按資源分,可以設置訪問設備A、訪問設備B等。
- 按操作分,可以設置讀取文件,寫入文件等。
例-1:權限分類示意圖
2.角色
角色是針對應用使用者來設置的,可分為管理員、技術人員,普通用戶等,也可按區域分為華北員工、華南員工等。
角色是一系列權限的集合,擁有某角色的用戶即應當自動擁有該角色下包含的權限。
圖-7:角色與權限關系示意圖
3.屬性
屬性是針對用戶層面下設置的獨立的安全設置,用來擴展和實現更細粒度的自定義安全設置數據,如將可訪問數據細化到數據庫中的表、數據表中的行、列上。
得益于JSON的兼容性,可以很靈活的存儲下這些自定義的結構化數據。
例-2:用戶屬性示意圖
4.ACL實踐
1.數據庫建模
依模型圖可以看出,一個應用可劃分多個角色、權限、路徑和屬性,其中角色又可包含同應用下的權限和路徑。一個用戶對應一個ACL,通過將不同的控制單元授予用戶,即可完成用戶的訪問控制配置。
2.配套功能設計
為了使訪問控制的整套機制良好的運轉起來,相關輔助和配套的功能也是不可缺少的,這里列舉一些我們已經投入使用的功能:
(1) 應用授權的分級、分組管理
不用業務應用的負責人可以分別對自己負責的業務進行授權管理,不會產生沖突和越權。
(2)應用菜單可見性、可訪問性的集成
業務應用中的各子功能可以和預先設置的權限一對一或一對多映射,具有相應權限的用戶才可以訪問和使用相應的功能,前后臺設置保持同步。
(3)應用下角色權限申請提交、授權變更、授權完成等自動化流程
基本的權限審批流減小了業務應用負責人和使用者之間的溝通成本,同時也記錄了權限獲取的記錄,為日后的安全審計提供了可查的數據。
(4)應用訪問日志收集、分析、審計、報警等
應用訪問日志記錄了更為詳細的用戶訪問和操作記錄,為安全審計提供了更完備的數據支持,同時也支持以一定的邏輯來分析和發現潛在的安全泄露風險。
五、總結
本文總結介紹了針對企業內網門戶的統一用戶管理、認證和授權管理的系統的組成部分和常見實現方法。使用開源CAS產品搭建的統一身份認證系統和定制化開發的安全訪問控制系統在企業內網平臺上得到了很好地實踐和應用,各部門的業務系統也已穩定接入并使用,目前運行良好。隨著系統規模和業務的增長,這一套平臺仍可能會面臨新的問題和挑戰,這也使得我們在收集用戶反饋的同時不斷的進行重構和增強,以保障企業業務的穩定發展。
項目地址:
https://github.com/cangelzz/cas-demo-django-server
https://github.com/cangelzz/cas-demo-flask-client
https://github.com/cangelzz/cas-demo-java-client
作者簡介:
程曉飛,高級全棧開發工程師 。2016年加入五阿哥鋼鐵電商平臺(wuage.com),曾供職于知名500強外企,精通Python,Java等多種編程語言及軟件開發技術,在企業內部Web系統、自動化工具開發方面有多年經驗。
最后給自己代個鹽~~歡迎大家有空時翻下我牌子(知乎專欄“開發運維”https://zhuanlan.zhihu.com/idevops),看看之前的文章,再點個贊唄,順便關注下。
【51CTO原創稿件,合作站點轉載請注明原文作者和出處為51CTO.com】