增強MIDAS的安全性 大家都知道,使用RemoteDataModule最令人頭疼的就是安全性問題。 主要體現在: 1、遠端只要知道應用服務器的端口號即可訪問到應用服務器,而一旦訪問到應用服務器,TClIEntDataSet即可獲得ProviderNames列表。(觀點:不讓他輕易得到ProviderNames列表。) 2、一旦知道了ProviderNames列表,這就相當於將數據庫暴露在外了。 例如:客戶端可以通過SQL語句來對數據庫進行操作了。(觀點:我們的應用服務器根部不接受SQL語句。) 因為看到大家此類貼多如牛毛,又沒有什麼更好的解決方法,因此我發表一下我的拙見。 我對IAPPServer接口進行了進一步的擴展,增強了RemoteDataModule的安全性。主要體現在: 1、客戶端偵測到應用服務器的端口號可以建立與應用服務器的連接,但必須提供由TClientDataSet提供一GUID作為密碼方能在設計階段獲得ProviderNames列表。此功能使得系統外部人員無法在設計階段直接在TClIEntDataSet的ProviderName中直接獲得應用服務器的TProvider實例。如果想通過IAPPServer來獲取ProviderNames列表則必須提供這一特定的GUID作為密碼。 IAPPServer的AS_GetProviderNames原形為 function AS_GetProviderNames: OleVariant; safecall; 擴展後的函數為 function AS_GetProviderNames(PassWord:WideString): OleVariant; safecall; 系統外部人員能夠訪問TRemoteDataModule的Provider的唯一方法就是猜測(或者成為蒙)出可能有的ProviderName直接賦值給TClIEntDataSet的ProviderName屬性。當然這是十分困難的(只要你不是直接將datasetProvider1作為TdatasetProvider的名稱)。 2、雖然惡意者可能通過其他方法(包括猜測、窮舉)來獲取到一個具有較高權限的TProvider,但是此步的安全特性完全將其擋在了門外。 TClIEntDataSet必須提供加密後的CommandText串才能得到應用服務的正確相應。因為這裡的加密對象是SQL語句(一個字符串),所以可以使用n多種加密方法。如果應用服務器解密出的串為非法SQL串,會向客戶端返回SQL語法錯誤信息。 而我在處理時並沒有對SQL進行真正的加密,而是在TClIEntDataSet的CommandText中包含了一特定的字符串作為鑰匙,而如果服務器得到請求後在CommandText中沒有找到這一鑰匙則返回“Missiong SQL property”異常。如果服務器得到了這一鑰匙,則將這一鑰匙從CommandText串中移除後交給TProvider進行處理。 實現: 聽上去好像很玄,但實現起來比較簡單: 我這裡簡單說說對SQL串的加密方法: 打開Provider單元,找到TDataSetProvider的SetCommandText方法。 你應該明白了吧。。。 如果你比我還菜,你就這樣寫: var commandt:string; begin if CommandText=\’\’ then Exit; if Copy(Commandtext,1,8)<>\’minercxy\’ then Exit; commandt:=Copy(CommandText,9,length(CommandText)-8); if not(poAllowCommandTet in Options) then DatabaseError(SCannotChangeCommandText); CheckDataSet; IProviderSupport(DataSet).PSSetCommandText(CommandT); end; 發布問題,編譯Provider單元並將Provider.dcu文件和並入應用服務器目錄中,編譯應用服務器。這樣TclIEntdataset必須提供\’minercxy\’+\’select * from ...\’ 這樣的命令才能被服務器承認。大的美女編輯們 我把\’minercxy\’暫且稱為鑰匙,鑰匙可以自己進行隨意設置,位數也可隨意長度。當然鑰匙的隨機性越大安全性就越強了。