2005年10月7日

簡易型『權限管理』機制

最近對『權限管理機制』的看法 一文中提到了對權限管理機制的看法,這次則來驗證一下目前正在構思中的 權限管理 機制的理論是否可行。

原始需求

企業目前打算建立一個專案管理系統,這個系統必須針對不同的專案關係人角色而提供不同的功能操作限制,已知的情形如下:
  1. 每一個專案關係人會參予多個專案,並在專案管理系統中留下專案的相關文件
  2. 每一個專案關係人在不同的專案下會有不同的身份
  3. 每一個專案關係人依其身份不同而有不同的系統操作權限

功能確認

此處確認由原始需求中所捕獲到的實際所需功能
  1. 可以查詢某使用者可以使用的資源種類
  2. 可以查詢某使用者是否具備某功能的使用權
  3. 可以查詢某使用者在不同的資源種類下可使用的功能

前提與假設

整個機制之所以運作的必要條件(呼叫端指的是專案管理系統本身;被呼叫端指的是權限管理機制):
  1. 呼叫端明確知道被驗證使用者的代碼及欲檢核功能的功能名稱/代號
  2. 呼叫端在必要時得主動向被呼叫端進行權限驗證程序

想法

  1. 所謂的權限控管機制不過就是作為權限設定資料與呼叫端之間的橋樑,所以只需規範對呼叫端開放的界面格式即可。
  2. 為了滿足第 1 個功能,提供一個函式 public String[] getResources( String username ) 給呼叫端。
  3. 為了滿足第 2 個功能,提供一個函式 public Boolean hasPermission( String username, String functionID ) 給呼叫端。
  4. 為了滿足第 3 個功能,提供一個函式 public Boolean hasPermission( String username, String resource, String functionID ) 給呼叫端。
  5. 選擇傳回 Boolean 而不是 boolean 是為了做三相檢查:可、否、無。

驗證

  1. 如何知道專案經理 John 能否使用編號 'F004' 的功能?
    檢查 hasPermission( "John", "F004" ) 的傳回值是否為 Bollean.True 後即可確認。若傳回值是 null 時則表示沒有 John 的設定,此時可以視為 John 不具有任何權限;也可解釋為 John 僅具有一般使用權限(也就是屬一般權限之使用者無需多做設定)。
  2. 如何知道專案經理 Micro 可以使用查看那些專案別的資料?
    透過取得 getResources( "Micro" ) 傳回的字串陣列可知道 Micro 可以存取的專案代碼。例如若傳回值為 { "P0001", "P3004", "P4005" } 可視為 Micro 可以存取 P0001、P3004 以及 P4005 等三個專案的相關資訊。
  3. Punk 在專案 P0003 中擔任專案經理,因此得以修改 P0003 的專案相關資料。同時 Punk 在專案 P2003 中擔任顧問一職,可以調閱 P2003 的專案記錄但不能進行修改。那麼 呼叫端該如何向權限控管機制確認上述的限制呢?
    1. 先取得與 Punk 有關的專案代碼,取得 P0003, P2003 兩筆記錄。
      String[] projects = getResources( "Punk" );
    2. 擷取專案記錄,例如使用 SQL 指令:
      select * from ProjectInfo where projectID in ( 'P0003', 'P2003' )
    3. 分別檢查 Punk 對每個專案資料的修改權為何:
      hasPermission( "Punk", "P0003", "MODIFY" ) == Boolean.True

      hasPermission( "Punk", "P2003", "MODIFY" ) == Boolean.False
    4. 依所取得的權限啟用/關閉對應功能之按鈕!

權限設定記錄的保存

就 hasPermission( username, functionID ) 而言,資料的記錄很單純。

ROWUserNameFunctionID
1JohnF004
2PunkMODIFY

若是多增加一個欄位 resource 即可符合 hasPermission( username, resource, functionID ) 的需要。

ROWUserNameResourceFunctionID
1John-F004
2PunkP0003MODIFY

那麼要如何記錄專案關係人所屬的專案別呢?這時候加欄位並無法滿足需求,但如果考慮另外建一個結構完全一模一樣的 Table 的話呢?

ROWUserNameResourceFunctionID
1MicroP0001-
2MicroP3004-
3MicroP4005-
4PunkP0003-
5PunkP2003-

看起來似乎可行,設定上也不會很複雜(雖然可能會有點繁瑣)。換句話說只要載入兩種設定檔後即可透過交互參考而確認出某個使用者的功能及資源上的限制與否。以 OO 的方式來思考整個機制後,會有類似以下的程式碼:

{
  /* 這個 code 採用類似 Java 的語法,請自行修改成所使用的語言規格 */
  // 載入所屬專案表
  AccessControl projectACL = new AccessControl( "ProjectInfo" );
  // 載入所屬功能表
  AccessControl functionACL = new AccessControl( "FunctionInfo" );

// 檢查 John 是否有 F004 的使用權 Boolean result = functionACL.hasPermission( "John", "F004" ); if ( result == null ) { // 沒有 John 的設定值 } else if ( result.booleanValue() == true ) { // John 可以執行 F004 的功能 } else if ( result.booleanValue() == false ) { // John 不可以執行 F004 的功能 }

// 取得 Micro 所屬的專案代碼 String[] projects = projectACL.getResources( "Micro" ); for( int i = 0; i < projects.length; i++ ) { Logger.info( "Project Code: " + projects[i] ); }

// 取得 Punk 所屬的專案代碼,且依專案別顯示可否修改內容 String[] projectsOfPunk = ProjectACL.getResources( "Punk" ); for( int j = 0; j < projectsOfPunk.length; j++ ) { String sql = "selet * from ProjectInfo "; sql += " where projectID = '" + projectsOfPunk[j] + "'"; ResultSet rs = sqlConnnection.execute( sql ); if( functionACL.getPermission( "Punk", projectsOfPunk[j], "MODIFY" ) == Boolean.TRUE ) { Logger.info( "Project: " + rs.getString( "ProjectName" ) + " is editable !" ); } else { Logger.info( "Project: " + rs.getString( "ProjectName" ) + " is not editable !" ); } }

除了透過資料庫保存外,也可使用一般文字檔、XML 檔等方式保存權限設定。

更進一步

當企業內員工人數眾多,為了不把時間浪費在逐一設定使用者權限的動作上,通常會引入 ROLE 的概念。

這個簡易型權限管理機制也可以很容易的達到這項要求喔!例如有一個記錄 ROLE 使用權限的表格如下:

ROWUserNameResourceFunctionID
1ROLE_EMP-F001
2ROLE_EMP-F004
3ROLE_EMP-F005
4ROLE_MGR-ADD
5ROLE_MGR-DELETE

驗證動作差不多就會像這樣:

{
  // 載入功能設定
  AccessControl userACL = new AccessControl( "FunctionInfo" );
  // 載入 Role 設定
  AccessControl roleACL = new AccessControl( "RoleInfo" );

// 用戶 Jay 是 ROLE_MGR 群組 // 先檢查 Jay 有無個人權限設定 Boolean result = userACL.getPermission( "Jay", "ADD" ); if( result == null ) { // 無個人權限設定 Boolean roleResult = roleACL.getPermission( "ROLE_MGR", "ADD" ); if( roleResult == null ) { // 也無角色權限設定 } else { // 有角色權限設定 } } else { // 有個人權限設定 } }

結論

優點

  1. 不管是開發還是設定都很單純。
  2. 使用上很直覺。
  3. 彈性大,可組合多個設定表而達到對資料、對功能、對身份等的權限控管。

缺點

  1. 檢核過程會隨著使用到的 Table 數而愈形複雜。
  2. 無法簡單支援階層式權限架構,也就是上位者之權限無法延申到基層員工的權限上。

可行性

  1. 需要參考到超過 2 個以上的 Table 的機會應該不高。
  2. 操作上的複雜度取決在應用系統本身,權限管理機制本身非常單純。
  3. 權限設定記錄可記錄在一般商用資料庫、XML 檔、甚至 LDAP 資料庫中,應用系統無需多加考量!
  4. 高層主管需要管理到基層員工的記錄嗎?或許不,但卻可能需要管理到基層主管的資料。

結論

  1. 是否設法納入階層式權限架構呢?
  2. 或許可嘗試建立此函式庫。

第一次接觸

不論相信與否,台灣人多多少少會接觸到了生活週遭中所存在的怪力亂神,最常見的情況大概就是 收驚 這檔子事了。

小時候每次遇到了反反覆覆的發燒情形,只要在西醫看個兩次、挨過兩針後還是沒有解決發燒的問題時,老人家就會說:『這是去驚到了,要去收驚才行!』然後說也奇怪,當道士在身上一陣鬼畫符、沒事灑了幾杯水、最後還喝了一點點的符水後,醫生給的藥才開始生效並且不再發燒。我相信絕大部份的成年人都有過這類型的奇妙經驗,當然包括我!

只是我與怪力亂神的第一次接觸還要更戲劇化些,如果曾看過年初時所留的那篇 神喻 應該會知道家父是濟公的乩身,整個故事還是一樣從收驚開始談起。

那年高二,因不明原因持續發燒一星期。每次打完針後就退燒,但隔日一早又會重覆發燒。在反反覆覆過了三天後家母終於做出去收驚的決定,並且隔日一早的確也就沒有發燒的情形。原以為事情就這麼結束,卻沒想到過了中午後又開始發燒,早退返家後家母也開始覺得事情似乎超乎想像複雜,決定要帶我去給濟公師父看看情況。

當時師父看了看我後,吩付要了一杯陰陽水並燒了一張符咒後要我喝下,而當我舌頭一接觸到那碗符水後看法就有了改變。

先聲明在那之前其實我是不太相信怪力亂神這種事的,但當我一接觸到那碗符水時卻發現到一股神秘力量在用力對我拉扯,等我好大容易站穩腳步且完成儀式後才知道原來我是被某種東西附身了,而剛剛感受到的那股拉扯力量則是在將其抽離我的身體時的反應。那個東西似乎沒有啥惡意,但我卻從此開始相信怪力亂神雖不能經科學證明,卻也無法透過科學加以否定。

隔日後就不再發燒(感冒的不算啦),這就是我與神力亂神的第一次接觸。

當然漸漸的接觸的次數多了後,就會產生更多的疑問,只不過夜深了,下次再聊!

註:

  1. 陰陽水:這指的是一半的開水 + 一半的自來水。另外還有『半天水』則是指椰子水,市面上似乎有在賣。
  2. 雖然是說喝符水,不過實際上是三小口,也別喝到符灰。

2005年10月6日

送3幼子上學 母被酒駕男撞死

新聞:
  1. Yahoo!奇摩新聞 - TVBS 新聞:送3幼子上學 母被酒駕男撞死
看法:
  1. 每次看到這種新聞,總是只能深深嘆息。
  2. 嘆息的是一條生命就此消逝,嘆息的是一家的幸福就此煙消雲散。
  3. 交通安全規定很多,可是目前還是有一堆酒駕事故,仍然有一堆騎車、開車時打手機的情形。台灣人的法規觀念究竟建立到那邊去了?
  4. 我不敢說沒有違反過任何一條交通法規,但重點還是在於 安全 而以。

2005年10月5日

對戰地風雲2的一些心得

玩了幾個月後,來談談 戰地風雲 2 的一些怪狀況吧!
  1. 評價兩極的防空飛彈:戰地 2 的防空飛彈(不管是車載的還是地面固定式的)在不同的情形下,其效果實在很天差地遠!打敵人時遜的要命;打自家人時卻又勇猛無比。更糟的是不論你的瞄準器是否已鎖定了敵機,那些離開發射架的飛彈卻總是經常往自家人的飛機殺過去,然後就看到畫面出現: 擊殺隊友 字眼…
  2. 莫名其妙的戰力平衡系統:有時真的很搞不懂 EA 對 平衡 兩個字的定義為何!當一方的戰力遠勝另一方時竟然是把勝方之中仍然是弱腳的傢伙往另一方踢過去而不是把第一或第二名丟過去以強化對方戰力。結果呢?當然敗方依然永遠還是敗方嘛!
  3. 沒有載具破壞分數:一輛坦克常要動用一個反坦克兵身上的所有反坦克火箭,結果 的一聲後只算擊斃敵 人,這分數真的有夠難賺… :@
其他的心得:
  1. 不知道為什麼,我在國外的 Server 上似乎比較難取得分數,但是在 EATW 中則通常有 2x 分的成績!不小心還可能取得金牌哩。
  2. 通常只要有人找我入隊,我都會接受。不過如果發現那些隊長混過頭也會自動辦理退隊事宜!
新發現:
  1. 以前嚇死人不償命的階級所需分數似乎修正了?看起來是為了讓玩家能快速解開隱藏武器以便維持人氣的樣子?
  2. 第二把要解那一隻槍哩?傷腦筋!

2005年10月4日

最近對『權限管理機制』的看法

幾乎每一套企業內部使用到的系統都得要有的機制是啥?我想十之八九會是『權限管理』機制吧!

說是權限管理機制,它不算困難,卻也不容易做的很有彈性。更進一步來說愈是高彈性的機制通常也就表示使用上得花一點力氣去操作,說起來也是蠻累人的!

權限管理通常分為兩部份: 身份認證 以及 存取控制

身份認證 比較簡單,反正就是給定待認證資訊後與系統進行比對並將結果回覆給呼叫端,最近的作法是透過 Microsoft 的 ActiveDirectory 機制以 LDAP 協定進行查詢即可。

存取控制 就討厭多了,通常會有以下的控制要求:

  1. 可否使用:具備某項功能的使用權
  2. 可否新增:具備某種資料的新增權
  3. 可否刪除:具備某種資料的刪除權
  4. 可否讀取:具備某種資料的讀取權
  5. 可否修改:具備某種資料的修改權
  6. 可以接觸的資源種類:有時候會有同一個人要管理多重資料來源的情形,此時會發生除了功能上的使用權問題外,還會發生資料上的使用權。例如:模組工程師可以查看所屬模組的相關資料;專案經理則可以接觸多個模組的資料等。
過去的想法是希望能用一個 Java Class 完成這方面的控制,這種作法會導致混雜兩種不同型式的存取設定,增添開發及後續維護上的複雜度。

目前的想法則是改為將功能的使用權與資料的使用權分別處理,可以想像的到的好處有:

  1. 需求單一:無論功能的使用權和資料的使用權是一項資源的使用概念。
  2. 開發/設定簡單:不管是設定或開發過程,都只需針對一種資源做管理。
  3. 符合使用流程:通常在企業系統的操作上是有先後順序的,一般都是先檢查功能的使用權後,再試結果再取得資料的使用權並完成對資料庫的資料擷取動作。
碰到的問題:
  1. 權限參數的取得:以前通常是存在資料庫中(可以用 Hibernate framework 擷取)或是放在 XML 檔中(可以使用 JAXB 擷取),不管那一種都要再研究一下。個人是覺得一來變動情形不大、二來資料量也不大的關係,想使用 XML 檔對應即可。
  2. 權限規劃的實作:要用 Role & User 作管理呢,還是以 User 為主即可?

2005年10月3日

羅文嘉:新民進黨運動 激起討論比沒討論好

新聞:
  1. Yahoo!奇摩新聞 - 中央社:羅文嘉:新民進黨運動 激起討論比沒討論好
  2. Yahoo!奇摩新聞 - 東森新聞報:繼「新民進黨」後 20立委要求成立禿鷹、高捷3個調委會
  3. Yahoo!奇摩新聞 - 中央社:回應新民進黨運動 綠委籲成立高捷等調委會
看法:
  1. 老實說民進黨執政五年來在政、經等方面的確並沒有帶給民眾耳目一新的感覺。啊!有啦,就是老喜歡放砲、推拖、撇清責任!
  2. 權力會使人腐朽果真是不變的真理,只不過才執政五年就立刻應驗也算是一種奇蹟!
  3. 雖說民進黨的施政受限於在野黨的箝制,但五年來看不到大是大非的作為,只有迎合在野黨的小招式。拜託,政府不是為在野黨服務耶,真是沒節操!
2008 年大選的看法:
  • 親民黨:果然是親近大陸人民
  • 中國國民黨:不愧為 中國 之名
  • 台聯:雖然以台灣為問政主軸,但太容易與大陸產生大摩擦
  • 民主進步黨:政策未能擇善固執,總是搖擺不定,人民難以產生信任感。

2005年10月1日

馬搭小巴趕路 二高遭警攔截勸導

新聞:
  1. Yahoo!奇摩新聞 - TVBS 新聞:馬搭小巴趕路 二高遭警攔截勸導
  2. Yahoo!奇摩新聞 - 中時電子報:佔內線道 馬險被開單
看法:
  1. 不管員警怎麼解釋,如果不是因為政治人物馬主席的話是不可能規勸了事的。
  2. 政治人物享有特權的案例,可證!