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

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