試一下下面的代碼,我們之前沒有使用 security 命名空間,但是我們現在來用用看。
using ?System.Security.Permissions;
添加另一個 button 到已經存在的 form 上。
{
???? try
????{
????????InitUI( 1 );?
????}
???? catch ?(SecurityException?err)
????{
????????MessageBox.Show(err.Message, " Security?Error " );
????}
???? catch ?(Exception?err)
????{
????????MessageBox.Show(err.Message, " Error " );
????}?
}
InitUI
只是調用
ShowUI
函數。記住它已經被拒絕了對
c
盤的讀操作。
// ?Note:?Using?declrative?syntax
[FileIOPermission(SecurityAction.Deny,Read = " C:\\ " )]
private ? void ?InitUI( int ?uino)
{
???? // ?Do?some?initializations
????ShowUI(uino);???? // ?call?ShowUI
}
ShowUI
函數得到
uino
顯示適當的
UI
。
{
???? switch ?(uino)
????{
???????? case ? 1 :? // ?That's?our?FileRead?UI
????????????ShowFileReadUI();
???????????? break ;
???????? case ? 2 :
???????????? // ?Show?someother?UI
???????????? break ;????????????
????}
}
ShowFileReadUI
顯示與讀文件有關的
UI
。
{
????MessageBox.Show( " Before?calling?demand " );
????FileIOPermission?myPerm? = ? new ?
??????FileIOPermission(FileIOPermissionAccess.Read,? " C:\\ " );
????myPerm.Demand();
??????? // ?All?callers?must?have?read?permission?to?C:?drive
?????? // ?Note:?Using?imperative?syntax
??????
???? // ?code?to?show?UI
????MessageBox.Show( " Showing?FileRead?UI " );
???? // ?This?is?excuted?if?only?the?Demand?is?successful.
}
我知道這是一個槽糕的例子,但是它已經足夠了。
現在運行我們的代碼。你會得到一個“ Before calling demand ”的消息,然后跳出一個自定義的錯誤對話框“ security error ”。哪里錯了呢?看下面的圖片:
【圖 11 】
我們已經禁止了
InitUI
方法的
讀的權限。所以當
ShowFileReadUI
請求對
c
盤的寫的權限的時候,它檢查堆棧的時候找到不是每個調用者都被允許這個
demanded permission
,顯示一個異常。只需要注釋在
InitUI
方法里面注釋
Deny
statement
,
它就可以工作了,因為所有的調用者都有
demanded
的
permission
。
?
注意,根據文檔,許多
.NET Framework
的類已經有了
demands
關聯它。例如
StreamReader
,
StreamReader
自動需要
FileIOPermission
.
所以用其他
demand
去替換它會導致一個堆棧的錯誤。
Link Demand
一個 link demand 只檢查你的代碼的直接調用者。那意味者它不會對堆棧起作用。當你的代碼跳到一個典型的引用,包括函數指針引用和方法調用會發生 link 。一個 link demand 只能用申明的方式。
private ? void ?MyMethod()
{
???? // ?Do?Something?
}
Inheritance Demand
Inheritance Demand 能過被類和方法應用。如果它用到一個類上,所有從它繼承的類都具有它的 permission
private ? class ?MyClass()
{
???? // ?what?ever
}
如果它用到一個方法上,所有繼承它的類必須制定 permission 去重寫那個方法。
{
???? public ? class ?MyClass()?{}
????
????[SecurityPermission(SecurityAction.InheritanceDemand)]
???? public ? virtual ? void ?MyMethod()
????{
???????? // ?Do?something
????}
}
就像 link demand , inheritance demand 也只能用聲明的方式。
Requesting Permissions
想象一個場景。你給一個用戶一個 form 其中包含有 20 多個 field 去填充,所有的信息必須保存在一個 text 文件中,用戶填充了所有的信息,當他要保存的時候,他得到了一個信息,他沒有足夠的權限去創建一個文件。當然你可以試圖沉靜的告訴他為什么會發生這個,因為我們調用堆棧的時候 ... 因為一個 demand 。。如果你足夠幸運,你可以從 microsoft 那得到這個警示(相信我 ... 有時他確實會發生)。
?
你在裝載裝配的時候請求 permission 的優先級是否比較容易呢?這里有 3 種方法去做他在 CAS 中。
-
RequestMinimum
-
RequestOptional
-
RequestRefuse
注意這些只能用聲明的語法應用在裝配的級別,而不是應用給方法或者是類。最棒的是管理員可以在裝配之后查看請求的 permissions ,使用 permview.exe 你可以查看它所被賦予的 permissions
RequestMinimum
你可以使用 requestMinimum 去指定 permissions 。代碼只允許在所有 permissions 都被賦予的時候才能夠跑。在下面的代碼片段中,有一個請求去寫注冊表的請求。如果這個沒有被安全機制賦予權限,這個裝配甚至不會被裝載。就像之前提到的,這種請求能夠在裝載的時候完成。
using ?System.Windows.Forms;
using ?System.IO;
using ?System.Security;
using ?System.Security.Permissions;
// ?placed?in?assembly?level
// ?using?declarative?syntax
[assembly:RegistryPermission(SecurityAction.RequestMinimum,?
?????????Write = " HKEY_LOCAL_MACHINE\\Software " )]
namespace ?SecurityApp
{
???? // ?Rest?of?the?implementation
}
RequestOptional
使用 RequestOptional ,你能指定你的代碼所需要的 permissions ,而不是跑的時候才請求。如果你的代碼沒有被賦予 optional permissions ,你必須處理代碼片段在執行時需要 optional permissions 而拋出的異常。這里有一些在使用 requestOptional 時必須注意的事情
如果你使用 RequestOptional 和 RequestMinimum ,除了他們兩再沒有其他的 permissions 將被賦予,如果被安全機制所允許。盡管安全機制允許添加 permissions 到你的裝配集,他們將不會被賦予。看下面的代碼片段:
[assembly:FileIOPermission(SecurityAction.RequestMinimum, Read=
"C:\\"
)]
[assembly:FileIOPermission(SecurityAction.RequestOptional, Write=
"C:\\"
)]
這個裝配集的
permissions
只是對文件系統的讀和寫。是否還需要顯示
UI
?然后這個裝配集被裝載,但是一個異常被拋出,當顯示
UI
的代碼被執行的時候,因為盡管安全機制允許
UIPermission
,
但是它沒有被裝配集允許。
RequestRefuse
你可以使用 RequestRefuse 去指定你確定不需要被賦予的 permissions 在你的代碼中,即使他們已經被安全機制賦予了,然后拒絕寫的 permission 將保證你的代碼不會被濫用
[assembly:FileIOPermission(SecurityAction.RequestRefuse, Write=
"C:\\"
)]
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
