實現基於角色的授權
Scott Crowther, 軟體工程師, IBM
Abe Guerra, 軟體工程師, IBM
Tamer Nassar, 軟體工程師, IBM
2009 年 6 月 29 日
瞭解如何通過使用者身份驗證實現一個動態的使用者介面。身份驗證通常是對具有多組使用者的應用程式的一種要求。每個使用者組都需要訪問某些應用程式功能,而這部分功能對於另一個使用者組可能需要進行限制。身份驗證機制必須要驗證使用者憑證並基於使用者憑證控制對應用程式功能的訪問。本文展示瞭如何使用 OpenLDAP 和 Tomcat 實現基本的身份驗證機制。本文將 OpenLDAP 和 Tomcat 實現與 OpenLDAP 和 WASCE 實現做了對比。最後,還通過例子展示瞭如何使用 Java™ 程式碼和 JSTL 實現這個動態 UI。
Web 應用程式通常需要控制特定的一組使用者所能使用的功能性。比如,一個應用程式可能會允許一組專業使用者嚮應用伺服器上傳資料檔案。但是,此應用程式需要防止一般的使用者也這麼做。
控制對應用程式功能的訪問是一個分為兩個步驟的過程。首先,使用身份驗證機制來辨識當前使用者。其次,使用授權機制來控制對應用程式功能的訪問。此過程的實現可能會涉及到應用程式 Web 頁面的多個副本,其中每組使用者分別具有此 Web 頁面的一個相關副本。本文建議並使用了另外一個實現,這個實現的目的是用 Web 頁面的一個副本來通過 Java 和 JSTL 動態呈現適當的功能性。
實現授權的技術很多。考慮到應用程式的複雜性,本文中的實現使用了一個應用伺服器。尤其是,我們使用了 Tomcat 6 和 WebSphere Application Server Community Edition 2.1 (WASCE)。之所以採用 WASCE 實現,是考慮到與 Apache Geronimo 的整合及其相關的 J2EE 平臺。
本文的實現使用了 Lightweight Directory Access Protocol (LDAP)。LDAP 實現提供了一種管理應用程式使用者所需的健壯機制。有若干個 LDAP 伺服器可供我們使用。我們所需要的 LDAP 伺服器應該是健壯、穩定和開源的。根據這些條件,我們做了一番研究,結果,OpenLDAP 成為了我們的最佳之選。
本文針對的是一個基於 Java 的 Web 應用程式。我們使用了 Java 5、JSF 1.2 和 JSTL 1.2。我們的 IDE 是帶 Web Tools Platform. (WTP) 的 Eclipse Ganymede 發行版(相關下載連結,請參見 參考資料)。
安裝了 Java 和 Eclipse 之後,就可以開始設定開發環境了。首先,需要通過如下步驟建立所需的專案庫:
- 從選單欄單擊 Windows。
- 選擇 Preferences。
- 在 Preferences 視窗中雙擊 Web。
- 雙擊 JavaServer Faces Tools(在 Web 下)。
- 選擇 Libraries(在 JavaServer Faces 下)。
- 單擊 New 以新增下述三個 jar 檔案:
- jstl-1.2.jar
- jsf-api.jar
- jsf-impl.jar
這時的 Preferences 視窗應該類似圖 1。
其次,需要通過如下步驟建立一個新的 Eclipse 專案:
- 從選單欄單擊 File。
- 懸停於下拉選單內的 New。
- 從第二個下拉選單中選擇 Dynamic Web Project(如果 Dynamic Web Project 沒有列出,可能需要通過 Other 選項找到該選項)。
|
由於進行的是 Tomcat 6 和 WASCE 部署,因此我們將需要在此處分別處理不同的伺服器。建立此專案的第一步是提供一個名字、目標執行時、模組版本和配置。它應類似圖 2 所示(基於這種情況下的設定和 Tomcat)。
第二個步驟要求配置 Web 模組設定。在這個步驟可以包括預設設定。第三個步驟要求定義專案的 JSF Capabilities,類似於圖 3。
|
現在,讓我們開始定義安全性。需要定義 Web 應用程式的安全約束。我們將定義這樣一種約束,這種約束將針對未經身份驗證的使用者保護 /WebContent/private 內的所有內容(我們將使用 UI 處理角色)。要建立這個約束,需要將清單 1 中所示程式碼新增到 /WebContent/WEB-INF/web.xml:
|
接下來,需要定義一個登入機制。我們將定義基於表單的身份驗證,並定義此表單的位置。將清單 2 中的程式碼新增到 web.xml:
|
我們需要對 web.xml 做的最後一個更新針對的是安全性角色。不過,由於我們通過 JSTL 處理角色,因此我們可以通過新增清單 3 中的程式碼來為所有角色定義約束。
|
為應用程式定義了安全性之後,還需要將其與一個用來管理 Web 應用程式使用者的 LDAP 解決方案進行連線。可以在 /WebContent/META-INF/context.xml 中定義 LDAP 伺服器。這個檔案類似於清單 4。
|
現在,我們要用 WASCE 建立這個基於角色的導航專案。在接下來的步驟中,我們將展示如何建立並配置這個專案以及如何在 WASCE 中設定 Security LDAP。
依照以下步驟建立一個新的專案:
- 單擊選單欄中的 File。
- 選擇 Dynamic Web Project。
- 鍵入專案名稱:RolesBasedNavWASCE
- 選擇 IBM WASCE 作為執行時。
- 在 Dynamic Web 模組下,選擇 Version 2.5。
- 為配置欄位選擇 JavaServer Faces。
- 單擊 Modify 並新增 WASCE Deployment。
定義專案的 JSF 功能。請參照下面內容設定這個 JSF:
下面介紹如何配置 WASCE 以連線到 LDAP。LDAP 可以安裝在同一個伺服器上,也可以安裝在不同的伺服器上。只要指定了正確的連線 URL,WASCE 就能連線上它。
- 訪問 WASCE admin 控制檯。進入 http://SERVERNAME:8080/console
- 以使用者名稱/密碼 system/manager 登入。
- 單擊 Security Realms。
- 為安全域鍵入名稱:ldap-realm,並選擇 LDAP Realm 作為 Realm Type。
- 單擊 Next。
需要在 Security Realm 頁面中輸入 LDAP 資訊以使 WASCE 可以與 LDAP 通訊。以下是基於我們的 LDAP 設定而需要輸入的欄位值。
- Initial Context Factory:com.sun.jndi.ldap.LdapCtxFactory
- Connection URL:"it should point to the LDAP server"
- Connect Username:cn=ldaproot,dc=tnc,dc=org
- Connect Password:xxxxxxx
- Confirm password:xxxxxxx
- Connect Protocol:"LEAVE IT BLANK"
- Authentication:simple
- User Base:ou=people,dc=tnc,dc=org
- User Search Matching:uid={0}
- User Search Subtree:false
- Role Base:ou=people,dc=tnc,dc=org
- Role Name:cn
- Role User Search String:(objectClass={0})
- Role Search Subtree:false
請注意:這些值可能會因您的 LDAP 設定的不同而有變化。
- 單擊 Next。
- 要測試 LDAP 連線,需要為所建立的 LDAP 使用者輸入一個使用者名稱/密碼。
- 測試成功後,單擊 Deploy Realm。
要完成安全性配置,需要定義一個用來保護 /WebContent/private 中所有內容的約束。要建立這個約束,可以將下面的內容新增到 web.xml:
|
另外,您還需要依照清單 6 來將這個安全域新增到 geronimo-web.xml。
|
這個專案和檔案結構與 Tomcat 專案一樣,其主要區別在於可以充分利用 WASCE 來進行開放 LDAP 的身份驗證。
比起 Tomcat,用 WASCE 有幾個優點:
- WASCE 支援完整的 J2EE 堆疊,它包括:一個 Servlet 容器、一個 EJB 容器、一個訊息提供者(JMS)和一個 Java Connector(JCA)容器。
- 像 Security 和 Authentication、Web Services、JMS 等服務均由 Geronimo Plug-in Kernel 提供。
- 支援 EJB 與 JPA。
- 額外的外掛也可被應用於 Kernel 並在應用程式程式碼內訪問,而不是嵌入在應用程式程式碼中。
- 群集提供了更好的可靠性及效能。
- 事務資料庫(Apache Derby)被包括在內。
- 集中化的配置和控制
- 執行時定製
- 集中化使用者管理
- Eclipse 外掛允許部署和除錯(甚至使用遠端方式)。
- 有關於遷移的文章,可幫助從 Tomcat/JBoss 遷移到 WASCE。
- 有 IBM 支援。
|
這個應用程式頁面將存在於兩個目錄中。需要安全性的專用頁面存在於 /WebContent/private 中。無安全性要求的公共頁面存在於 /WebContent/public 中。
這個公共目錄包括不要求身份驗證的 html 頁面,其中包括登入頁面及錯誤頁面。依照以下步驟來建立登入頁面:
- 右鍵單擊 public directory。
- 滑鼠懸停於選單內的 New 上。
- 在第二個選單上單擊 HTML。
- 設定登入名稱並單擊 Finish。
使用預設的身份驗證機制,但它要求必須將登入表單的動作定義為 j_security_check,並使用 j_username 和 j_password。得到的 html 檔案如清單 7 所示:
|
類似的,在公共目錄中建立另一個 HTML 檔案並將其命名為 loginError.html。這將是當使用者試圖用無效憑證登入時所顯示的頁面。清單 8 顯示了這個頁面:
|
您一定還想建立一個類似的頁面來顯示錯誤訊息,當一個使用者請求訪問他或她未被授權的功能時,就會顯示錯誤訊息。這個頁面很簡單,如清單 9 所示。
|
在這個示例中,我們將使用一個簡單的主頁,它將模擬到應用程式功能的連結。我們還將建立 .jsp 頁面,它將模擬應用程式中的不同型別的功能。所有這些檔案都要被放在受保護的區域中(/WebContent/private)。這個主頁將使用清單 10 中匯入的標記庫:
這個 .jsp 頁面還使用了一個資源包以使內容可以被外部化:
這個 .jsp 頁面是靠後端 Java 程式碼來進行使用者身份驗證的。一旦使用者通過針對 LDAP 目錄的身份驗證,它們的憑證將通過 Java beans 持久化。.jsp 可以如清單 11 所示的那樣引用 bean:
在上面的片段中,一個歡迎訊息通過綜合來自資源包(由 'msg' 引用)的內容和來自這個 Java bean(由 userBean 引用)的姓名而被顯示出來。在這時,我們可以根據使用者的角色開始過濾。使用者的角色也包含在 Java bean 中。這讓 .jsp 頁面可以檢查使用者的角色並採取恰當的動作。例如,您可以控制基於當前的使用者角色而被顯示出來的功能連結。
|
清單 12 中的程式碼片段檢查當前使用者的角色是否是 ‘Admin’。如果是,它將顯示 admin 功能的連結。如果不是,則不顯示這個連結。我們將在這個 .jsp 頁面中增加額外的檢查,以便模擬保護功能頁面免受直接訪問的功能。得到的主頁應類似清單 13:
|
我們將在專用目錄中建立另外三個 .jsp 頁面,每個頁面針對一種所模擬的功能:casual、expert、admin。如我們前面提到的,我們需要在 .jsp 頁面中做另一個檢查來避免對 .jsp 頁面的直接訪問。可以按清單 14 所示內容來進行這個檢查:
在上面的程式碼片段中,我們檢查是否有預期的使用者角色。如果這個使用者角色不是我們預期的,就會把使用者重定向到一個錯誤頁面。對於 casual 功能我們則不需要做這種檢查,因為它對所有通過驗證的使用者都是開放的。
casual 功能頁面應類似清單 15:
|
expert 功能頁面如清單 16 所示:
|
admin 功能如清單 17 所示:
|
現在的目錄結構應類似下面的這個導航皮膚:
出於本文的目的考慮,我們將所有後端程式碼放進一個程式包中,我們將這個程式包命名為 com.ibm.test。可以通過以下的步驟來建立這個程式包:
- 右鍵單擊左側導航皮膚上的 Java Resources: src。
- 選擇 New 然後選擇 Package。
- 在名稱欄位中輸入 com.ibm.test 然後單擊 Finish。
我們後面將要使用一個資源包,所以我們先依照下面的步驟來建立一個資源包:
- 右鍵單擊新建立的程式包。
- 選擇 New 然後選擇 Other。
- 雙擊新彈出視窗中的 General。
- 選擇 File 然後單擊 Next。
- 在名稱欄位中輸入 messages.properties,然後單擊 Finish。
本文中的這個示例僅為歡迎頁面使用了資源包,因此,它只需下面這行程式碼:
welcome=Welcome |
然而,這個檔案完全可以包括應用程式的所有內容。
應用程式的身份驗證是由一個名為 UserBean 的 Java 類處理的。通過下面的步驟來建立它:
- 右鍵單擊 com.ibm.test package。
- 選擇 New 然後選擇 Class。
- 在名稱欄位中輸入 UserBean 並單擊 Finish。
這個 UserBean 類將使用兩個 Java 設計模式:Data Access Object (DAO) 和 Transfer Object (TO)。DAO 負責訪問來自於 LDAP 目錄的使用者資料。TO 負責儲存這些資料。UserBean 類將針對 home.jsp 的引用進行例項化:
UserBean 類的建構函式需要獲取通過身份驗證的使用者的 ID。記住,我們正在使用的身份驗證機制是 Tomcat 的預設表單身份驗證。從本文的目的出發,我們將用 Tomcat 處理身份驗證,並使用 UserBean 類獲取並持久化通過驗證的使用者的資料。我們可以從 UserBean 類中獲取使用者 ID,見下面程式碼:
ExternalContext context = FacesContext.getCurrentInstance().getExternalContext(); String userID = context.getRemoteUser(); |
我們現在可以使用通過驗證的使用者的 ID 來從 LDAP 目錄中檢索所有使用者資料。OpenLDAPDAO 類可實現此目的。依照以下步驟建立此類:
- 右鍵單擊 com.ibm.test package。
- 選擇 New 然後選擇 Class。
- 在名稱欄位中輸入 OpenLDAPDAO 並單擊 Finish。
OpenLDAPDAO 類在類變數中包含 LDAP 目錄的細節。其建構函式將會建立一個對 LDAP 目錄的連線。此外,還將包含一個方法,用來檢索特定使用者的屬性。UserBean 類通過 UserTransferObject 類保持使用者資料。這個類是一個使用者資料的容器。本文隨附的歸檔檔案中包含了所有類的一個副本。
這時的 Java 目錄結構應該與圖 11 中的導航皮膚結構相似。
大功告成了!不妨啟動伺服器並對它做個測試。
如果未通過身份驗證,嘗試訪問主頁時,將會被重定向到登入頁面,如圖 12 所示。
作為一個 casual 使用者,登入時將只會列出功能連結中的一個,如圖 13 所示。
如果使用者想要直接訪問 .jsp 頁面上一個未被授權的功能,就會顯示使用者錯誤訊息,如圖 14 所示。
以 admin 身份登入時,所有功能的連結都會出現,見圖 15。
|
祝賀您!在很短的時間裡,您就已經建立了一個能實現授權的骨架應用程式。您現在可以圍繞著這個骨架,構建一個能夠基於您在 LDAP 目錄中定義的使用者角色控制對功能的訪問的應用程式。您可以在 Tomcat 或 WASCE 上繼續開發您的應用程式,還可以充分利用它的其他功能。這個應用程式骨架還實現了 JSF,本文沒有對此做過多介紹,但它很值得深入研究。
值得研究的另一點是 OpenLDAP。有關設定 OpenLDAP 的內容就可以自成一篇文章了。OpenLDAP Web 站點是一個豐富的資源。第三方軟體可用來協助 LDAP 伺服器的管理。我們發現 Jxplorer 是一個很好的工具。不過,您可能會希望為應用程式實現一個管理部分,這樣,管理員可以通過此應用程式來管理 LDAP 伺服器。通過使用現有的模板加上 JSF,可以很容易地將它構建到這個應用程式骨架中去。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/14789789/viewspace-610871/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- MongoDB 6.0 單例項基於使用者角色實現授權登入MongoDB單例
- golang 基於 jwt 實現的登入授權GolangJWT
- 基於Docker的MongoDB實現授權訪問DockerMongoDB
- Asp.net中基於Forms驗證的角色驗證授權ASP.NETORM
- 使用 Laravel Gate 授權方式實現一個基於使用者角色的部落格釋出系統Laravel
- express基於JWT實現使用者登陸授權ExpressJWT
- 微信授權註冊或微信登陸 微信授權登陸 基於若依vue 實現Vue
- 基於 SASL/SCRAM 讓 Kafka 實現動態授權認證Kafka
- Oracle使用者、授權、角色管理Oracle
- Keycloak中授權的實現
- 系統多種使用者角色認證登入授權如何實現?
- 基於角色的許可權系統的問題
- ASP.NET Core 中基於策略的授權ASP.NET
- Oracle建立使用者、角色、授權、建表Oracle
- Jenkins配置基於角色的專案許可權管理Jenkins
- Quarkus中基於角色的許可權訪問控制教程
- 認證授權的設計與實現
- 基於RBAC實現許可權管理
- 讀到的"關於授權"
- k8s 基於RBAC的認證、授權介紹和實踐K8S
- 基於.NetCore3.1系列 —— 認證授權方案之授權揭祕 (下篇)NetCore
- 【ASP.NET Core】按使用者角色授權ASP.NET
- ASP.NET Core Web API下基於Keycloak的多租戶使用者授權的實現ASP.NETWebAPI
- 白話講解函式計算中的角色授權函式
- 【認證與授權】2、基於session的認證方式Session
- Spring Authorization Server 實現授權中心SpringServer
- Paypal授權登入流程及實現
- Laravel + JWT 實現 API 跨域授權LaravelJWTAPI跨域
- Shiro實現使用者授權
- [WCF許可權控制]基於Windows使用者組的授權方式[上篇]Windows
- .NET雲原生應用實踐(四):基於Keycloak的認證與授權
- 第三方微信登入 | 靜默授權與網頁授權的實現網頁
- 基於Taro框架的微信小程式JWT授權登入方案框架微信小程式JWT
- 基於HMAC-SHA1的RESTful API 授權簽名方法MacRESTAPI
- Think Authz:支援 ACL、RBAC、ABAC 等模型的授權(角色和許可權控制)庫模型
- ajax 實現微信網頁授權登入網頁
- 使用OPA實現Spring安全授權 | baeldungSpring
- .NET雲原生應用實踐(四):基於Keycloak的認證與授權AL