安全管理是最復雜也是最難以理解的功能模塊,理論上僅對系統管理員開放該功能。總的來看安全管理主要分為用戶管理、用戶權限、角色來分派權限。
在介紹安全管理之前,先讓我們對一些關鍵字有所了解。
關鍵詞:
ü
用戶:權限的持有者。一般來說通過登錄賬號對應客觀世界的一個人,一個用戶有且只能在一個部門下。用戶在權限系統中又分為不同的類型:一般用戶/超級管理員(不受權限限制,在應用系統中有無限的權力)
ü
權限:一個權限對應一個功能,這個功能可以是頁面/頁面中的表單元素(如按鈕/文本框)/業務層的方法,在技術層面看,一個權限只是一個字符串。目的是用戶擁有的權限與功能的配置權限做匹配,以達到權限驗證效果
ü
角色:權限的集合,因為權限的顆粒度太小無法滿足對一個完整業務授權管理的描述。如會計角色,要求可以增加、刪除與修改會計科目(或更多),而增加或刪除會計科目均是一個功能單元應分別對應各自的權限。在應用系統中,一個角色實際上就是一個工作職能所擁有的權限集合。
ü
組織結構:是用戶與部門的總稱。部門應是樹形結構。之所以在權限管理中引用組織結構,是因為影響權限對數據的篩選范圍。對于范圍可以分為:用戶級(當前用戶自己創建的記錄)/系統級(所有記錄)/當前部門級(當前用戶所在的部門中所有用戶創建的記錄)/部門級/部門及子部門級。對于后兩種類型還需要授權時給出參考部門。
操作方案:
方案1. 將多個權限直截分派給用戶
方案2. 將多個權限合并為一個角色,再將多個角色分派給用戶
此兩種方案是按系統復雜程度逐級遞增的,從權限的維護難度來看也是逐級遞增。在此要注意,在一個應用系統中您只能選擇兩種方案其中的一種來維護您的權限管理,強烈不推薦多種方案在同一個應用系統中同時管理的情況出現。這樣會導致后期系統維護的混亂,嚴重時有可能產生系統癱瘓!
通過用操作:
在分派某些查詢權限時頁面中會顯示范圍與部門

在范圍中只有部門級與部門及子部門極,部門一列才會顯示。權限控制范圍(以訂單為例)如下:
²
用戶級:只能看到當前用戶自己所創建的訂單
²
當前部門級:如果當前用戶與訂單的創建人在同一個部門,則當前用戶在查詢訂單時可以看到該訂單
²
部門級:可以為當前用戶指定一個部門,使他只能看到這個部門下所有員工所創建的訂單
²
部門及子部門級:可以為當前用戶指定一個部門,使他可以能看到這個部門包括這個部門下所有的子孫部門中所有員工所創建的訂單(部門或者說是組織結構應是樹形結構)
²
系統級:能看到所有訂單不受到任何組織結構及創建人的限制
用戶管理:
提供系統管理員對企業內與企業外用戶的安全認證管理。雖然在此處提供刪除用戶的功能,但不推薦使用。一般來說無論是新增還是刪除員工、客戶聯系人都應是人力資源或是銷售部門來管理,而系統管理員只對于這些用戶做授權或分派帳號與密碼。

²
姓名:用戶的真實姓名,見意系統管理員不要修改該內容,應由相關部門來維護該用戶的姓名,如人力資源部、銷售部、采購部的人員來修改該用戶的姓名
²
部門:是個抽象的概念,如果當前用戶是企業內部員工則它是企業內的部門或是分公司;如果當前用戶是客戶聯系人則它是客戶;如果當前用戶是供應商聯系人則它是供應商。同樣的該信息應用相關部門的負責來維護,系統管理員不應隨意修改
²
帳號:當前用戶登錄系統的帳號
²
密碼:當前用戶登錄系統的密碼,注意密碼經過了加密處理在修改密碼時一定要將該文本框中的內容全部清空后重新輸入,否則用戶將無法登錄系統
²
帳號可用:用以設定該帳號是否可用,如果為否則該帳號無效,用戶不能登錄系統
²
加鎖:對該帳號加鎖,加鎖后的帳號無法登錄到系統。加鎖與不可用表現形式相同即用戶無法登錄系統;區別在于加鎖相當于將凍結該帳號在一段時間后來可以解鎖,而不可用則是這個帳號常期失效后期對該帳號的用戶不予維護例如員工離職時一定要將帳號設為不可用而非加鎖
²
有效期至:可以為某個用戶的帳號設置有效期,當超過有效期即使帳號是可用未加鎖也無法登錄到系統中,如果不填寫用效期則視為該帳號不受時間限制始終可用
²
用戶類型:分為
n
超級管理員:不受任何權限的限制,在應用系統中有無限的權力,可以看到與修改全部內容
n
一般用戶:只能看到與修改他/她所擁有權限的內容
n
管理員:可以將自己已有的權限分派給他人
用戶權限:
對應操作方案中的方案1,即將權限直截分派給指定的用戶。這種方案適用于小型且用戶數量很少的應用系統。該方案優點是操作直觀易于理解,缺點是不易管理。
在為用戶分派權限時,可以通過三種操作方式來完成。

在操作過程中,當您選擇在不同用戶間來回切換時,當前頁面會自動刷新在“事項”一列只有是該用戶所擁有的權限才會被選中,您可以在此為用戶添加權限。頁面最上部的是一排菜單項,在每個菜單項中都會有多個權限,在您在不同的菜單項中切換時,頁面底部的權限列表會隨之改變。對于權限范圍與部門的處理請參見通用操作
3.
通過
按鈕,可以同時為多個用戶分配多個權限。

在操作過程中,你可以通過查詢條件查詢到您要選擇的用戶,人員列表的最左則提供選取人員的復框,即表示您要對這些選中的用戶進行批量授權。初始時權限列表的“事項”一列均未選中,您可以在此為選中的多個用戶添加權限。頁面中部的是一排菜單項,在每個菜單項中都會有多個權限,在您在不同的菜單項中切換時,頁面底部的權限列表會隨之改變。對于權限范圍與部門的處理請參見通用操作
“單用戶批量授權”與“多用戶批量授權”的差異在于,在單用戶批量授權中您可以看到所選中的用戶目前所擁有的權限,而多用戶批量授權則不能。
注意,無論是單用戶批量授權還是多用戶批量授權均不提供權限的刪除功能,原因是同一個權限在同一個用戶中有可能會有多個權限范圍不同的副本,系統無法判斷要刪除這個用戶這個權限的那一個副本。如果要為某個用戶刪除某些權限,可以通過用戶權限列表刪除之。
角色:
對應操作方案中的方案2,即將多個權限合并為一個角色,再將該角色分派給指定的用戶。這種方案適用于中小型企業的應用系統。該方案優點操作簡捷使用得當配置效率會很高,強烈推薦使用該方案實現安全管理。

²
角色名稱:必須填寫項,為角色定義一個名稱中英文均可
²
描述:對該角色的描述
²
顯示信息:沒有意義,可以不填
在操作過程中,您必須為角色賦予一個名稱,并填寫該角色的描述信息,以方便日后記憶。頁面底部的權限列表右側的“事項”一列會顯示該角色所擁有的權限,您可以在此為角色添加權限也可以為角色刪除某些權限。頁面中部的是一排菜單項,在每個菜單項中都會有多個權限,在您在不同的菜單項中切換時頁面底部的權限列表會隨之改變。對于權限范圍與部門的處理請參見通用操作
步驟2. 將角色分派給用戶

在操作過程中,你可以通過查詢條件查詢到您要選擇的用戶,人員列表的最左則提供選取人員的復框,即表示您要對這些選中的用戶分派當前角色。頁面的左下方是當前角色所擁有的權限,頁面的右下方為所有擁有當前角色的用戶列表,您可以通過用戶列表“事項”
刪除指定用戶所擁有的當前角色。
目的
一般對于應用系統的授權過程:
權限
à角色(部門) à用戶
過程描述:管理員將所要分組的權限分派給一個角色(一般會對應實際工作中一個崗位如出納/倉庫管理員…),并為當前角色指定一個部門(表示這個崗位是對哪個部門的管理)。
由此我們會發現,這個授權過程是鏈式的,即授權是一環套一環的,沒有上一個環節的支持下一個環節就不能工作。本系統的實現目的正是為了打破授權的這種鏈式結構,實現在不同授權環節間的跳躍。如可以直接為用戶分派權限,為用戶分配角色等。
相關技術與依賴
Acegisecurity是基于SpringFramework的Web應用中安全框架,通過過濾器(javax.servlet.Filter)與攔截器(org.aopalliance.intercept.MethodInterceptor),于web的所請求的頁面與所調用的方法進行攔截。以達到權限驗證的目的。在本系統中作為身份驗證與技術層上的授權實現的基本骨架。本文檔假設對Acegi框架已有全面的了解。
Spring是AOP與IOC功能強大的邏輯層框架,本系統中邏輯層的調用均基于該框架
限制
ü
本系統所有驗證與授權均是基于數據庫的,不支持其它方式業務層面上的授權
ü
由于采用上述相關技術本系統僅限于在web上的應用,不支持C/S結構
ü
由于復雜度與適用性的原因,本系統不支持頁面中各表單元素的權限可配置
ü
為了達到與部門有關的數據過濾的效果,所有業務相關的表中都要多加一個creator字段,作用是識標當前記錄的創建人(由創建人可以找到部門),并且與業務表對應的POJO的屬性名也應為creator
客戶端用戶授權處理
ü
權限管理(Authority):所有業務組件的權限均應由平臺生成器自動生,并自動插入到數據庫表,不提供終端用戶對權限操作界面。如果開發階段只能手動將權限插入數據庫表中。
ü
角色管理(Role/ RoleAuthority):在功能上分為角色的創建與刪除這兩部分
1)
創建角色:創建角色的過程實際上也是為該角色分派權限的過程。按菜單層次結構列出所有權限(如果是管理員則只能列出所擁有的權限),并且只是權限類型是查詢的,才會顯示參考部門與范圍,默認部門為空,范圍為系統級。保存時,在Role表中增加一條記錄,在RoleAuthority表根據終端用戶所選擇的權限及參考部門/范圍等信息,增加n記錄
2)
刪除角色:首先是否有用戶引用< UserRole >該角色,如果有引用則客戶端拋出警告,否則刪除Role/ RoleAuthority的相關記錄
ü
分派權限管理(UserAuthority):左側是組織結構樹右側為以菜單層次結構的權限列表(如果是管理員則只能列出所擁有的權限) ,并且只是權限類型是查詢的,才會顯示參考部門與范圍,默認部門為空,范圍為系統級。
ü
分派角色(UserRole):左側是組織結構樹右側為角色列表,將與該角色s對應的<RoleAuthority>的信息賦到<UserAuthority>表中
頁面表單的權限控制:由Acegi提供的taglib控制
對象定義源資源格式
平臺為了方便對權限的對象定義源資源進行管理與擴展提供兩種解決方案
方案一 現資源束形式管理
為了系統可以批量加載對象定義源實現資源束形式的管理,應提供對象定義源資源束格式的規范
1. 所有對象定義源的資源束文件均為properties文件,文件格式按properties規范處理,文件名為*-security.properties.生成器會自動將這些文件生成在java源代碼的相應的服務包下
2. 文件內容針對不同的安全功能提供不同的開始/截止符作用功能分隔。它們分別為對于URL安全控制的為WEB_SECURITY/WEB_SECURITY_END,對于業務方法安全控制的開始/截止符分別為BUSINESS_SECURITY/BUSINESS_SECURITY_END。
方案二 數據庫表形式管理
將所有權限對象定義源存放到數據庫表HI_PrivilegeResource中,表結構如下:
字段名
|
數據類型
|
唯一
|
描述
|
id
|
int
|
Y
|
主鍵ID
|
version
|
Int
|
|
樂觀鎖定時的版本控制
|
authorityName
|
String(200)
|
Y
|
權限名
|
viewLayer
|
String(200)
|
|
表現層的動作,一般的對應一個action的url
|
veiwExtAuthNames
|
String(200)
|
|
該表現層動作還可容許訪問的權限名,如果是多個權限用逗號(,)分隔
|
businessLayer
|
String(500)
|
|
業務層的方法,一般是類的全限定名包括方法名
|
bizExtAuthNames
|
String(200)
|
|
該業務層方法還可容許訪問的權限名,如果是多個權限用逗號(,)分隔
|
與權限相關的配置文件
平臺對于權限相關的配置文件存放在WEB_HOME/WEB-INFOr/config目錄下,文件名為appContext-security.xml是一個Spring的配置文件,由于該文件較為復雜在此僅介紹常用的幾處,具體的每段配置的目的請參見附錄中Acgei與配置文件相關的類說明
<bean id="securityManager" parent="txProxyTemplate">
<property name="target">
<bean class="org.hi.framework.security.service.impl.SecurityManagerImpl">
<property name="DAO" ref="org.hi.framework.dao.DAO"/>
<property name="userClass" value="org.hi.base.organization.model.HiUser"/>
<property name="userAuthorityClass" value="org.hi.framework.security.model.UserAuthority"/>
</bean>
</property>
</bean>
安全管理器是后臺的服務類,用于獲取給定用戶(即當前登錄用戶)的相關信息包括該用戶的POJO、該用戶所擁有的權限、角色等。UserContextHelper這個類在我們開發過程中經常用到它可以獲得當前用戶的所有信息,而這些信息的來源與組裝過程就是在安全管理器這個服務類中完成的。該類中的userClass屬性是指定用戶POJO的類型,如果我們通過擴展實體的方式擴展了HiUser,應將該類型更改為擴展后實體的POJO類型
<bean id="filterInvocationInterceptor" class="org.hi.framework.security.acegi.ResourceBindleFilterSecurityInterceptor">
<property name="authenticationManager"><ref bean="authenticationManager"/></property>
<property name="accessDecisionManager"><ref local="accessDecisionManager"/></property>
<property name="mappingLocations"><value>classpath*:/**/*-security.properties</value></property>
<property name="alwaysReauthenticate" value="true"/>
<property name="runAsManager"><ref bean="runAsManager"/></property>
</bean>
表現層也就是Action的攔截器,通過HttpFilter在servlet執行任意一個action之前先被攔截認證當前用戶是否有執行該url的權限,上面是資源束形式的管理方式,如要實現數據庫表形式的管理方式,如下
<bean id="filterInvocationInterceptor" class="org.hi.framework.security.acegi.DataBaseFilterSecurityInterceptor">
<property name="authenticationManager"><ref bean="authenticationManager"/></property>
<property name="accessDecisionManager"><ref local="accessDecisionManager"/></property>
<property name="load" value="true"></property>
<property name="alwaysReauthenticate" value="true"/>
<property name="runAsManager"><ref bean="runAsManager"/></property>
</bean>
對于業務層的方法攔截器,資源束形式管理/數據庫表形式管理,在配置上完全一致。
1.1
組織結構
從企業管理的角度來看,組織結構是指對于工作任務如何進行分工、分組和協調合作。從而使企業在組織上更加結構化、合理化以提高生產效率;從程序設計的角度來看,軟件系統應適應企業組織在結構上的不斷變化。
為了達到如上的要求,平臺在設計上對于Hi_Org和Hi_User是兩個抽象的表結構,對于Hi_Org來說它可以是公司、部門、客戶、供應商等等;而對于Hi_User來說它可以是員工、客戶聯系人、供應商聯系人等。因此在開發時可以通過平臺繼承實體的方式,擴展組織與人員實體從而實現不同類型的組織結構。
數據庫表結構
Hi_Org組織表
字段名
|
數據類型
|
唯一
|
描述
|
ID
|
int
|
Y
|
主鍵ID
|
version
|
int
|
|
樂觀鎖定時的版本控制
|
orgName
|
String(50)
|
|
部門
|
orgNum
|
String(10)
|
|
部門編號
|
manager
|
int
|
|
部門的管理者,<User>
|
parentOrg
|
int
|
|
父部門,默認為0 <Org>
|
address
|
String(100)
|
|
地址
|
description
|
String(500)
|
|
備注/描述
|
Hi_User用戶表
字段名
|
數據類型
|
唯一
|
描述
|
ID
|
int
|
Y
|
主鍵ID
|
version
|
Int
|
|
樂觀鎖定時的版本控制
|
userName
|
String(30)
|
Y
|
用戶的登錄賬號
|
password
|
String(100)
|
|
用戶密碼,在數據庫要求加密
|
country
|
int
|
|
對應枚舉表[Language],是i18n的語種
|
timeZone
|
int
|
|
對應枚舉表[TimeZone],是i18n的時區
|
accountEnabled
|
int
|
|
[YesNo],該帳號是否可用
|
accountLocked
|
int
|
|
[YesNo],是否鎖住該帳號
|
expiredDate
|
Date
|
|
帳號的失效日期,null為永不失效
|
credentialsExpired
|
int
|
|
[YesNo],密碼是否過期,預留不實現
|
fullName
|
String(30)
|
|
姓名
|
org
|
int
|
|
用戶所在的部門
<Org>
|
gender
|
int
|
|
性別
|
address
|
String(200)
|
|
地址
|
phone
|
String(50)
|
|
電話
|
mobile
|
String(50)
|
|
手機
|
zip
|
String(30)
|
|
郵編
|
SSN
|
String(50)
|
|
證件號
|
mail
|
String(100)
|
|
電子郵箱
|
userMgrType
|
int
|
|
[ScurityUserMgrType] 超級管理員/管理員/一般用戶
|
description
|
String(500)
|
|
備注/描述
|