建議121:爲應用程序設定運行權限
在某些情況下,可能存在這樣的需求:只有系統管理員才能訪問某應用程序的若干功能。這個時候,可以結合.NET中提供的代碼訪問安全性(Code Access Security)和基於角色(Role-Based Security)的安全性去實現。
如果要通過一下的代碼正常的訪問類型SampleClass,用戶必須以Administrator的身份運行代碼:
class Program { static void Main() { AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal); SampleClass sample = new SampleClass(); Console.WriteLine("代碼成功運行..."); } } [PrincipalPermission(SecurityAction.Demand, Role = @"Administrator")] //[PrincipalPermission(SecurityAction.Demand, Role = @"Users")] class SampleClass { }
如果恰巧我們是以User用戶組的用戶登錄系統的,則會拋出異常System.Security.SecurityException:對主體權限的請求失敗。只要還原上文中的那條註釋的屬性,就能讓代碼正確運行。
可以爲類型增加多條PrincipalPermission屬性,多個PrincipalPermission屬性之間是“OR”的關係。
對於代碼的控制可以細化到方法,代碼如下:
class Program { static void Main() { AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal); SampleClass sample = new SampleClass(); sample.SampleMethod(); sample.SampleMethodSec(); Console.WriteLine("代碼成功運行..."); } } class SampleClass { public void SampleMethod() { Console.WriteLine("執行方法SampleMethod"); } [PrincipalPermission(SecurityAction.Demand, Role = @"Administrator")] //[PrincipalPermission(SecurityAction.Demand, Role = @"Users")] public void SampleMethodSec() { Console.WriteLine("執行方法SampleMethodSec"); } }
這段代碼如果不是以Administrator身份運行的,則在執行完畢SampleMethod方法後也會拋出SecurityException。
除了使用Windows用戶和角色,我們還可以使用用戶自定義的主體。比如在一個考試系統中,只有教師才能修改成績,而考生只能具備瀏覽功能。爲了充分了解代碼的機制,以下代碼我們不用屬性聲明的方式:
class Program { static void Main() { GenericIdentity examIdentity = new GenericIdentity("ExamUser"); //String[] Users = { "Teacher", "Student" }; String[] Users = { "Student" }; GenericPrincipal MyPrincipal = new GenericPrincipal(examIdentity, Users); Thread.CurrentPrincipal = MyPrincipal; ScoreProcessor score = new ScoreProcessor(); score.Update(); } } class ScoreProcessor { public void Update() { try { PrincipalPermission MyPermission = new PrincipalPermission("ExamUser", "Teacher"); MyPermission.Demand(); //省略 Console.WriteLine("修改成績成功"); } catch (SecurityException e) { Console.WriteLine(e.Message); } } }
以上代碼運行時會拋出異常,因爲我們在調用Update方法的時候只配置了Student組。要使代碼能夠成功運行,應該在調用處使用註釋掉的那行代碼。
轉自:《編寫高質量代碼改善C#程序的157個建議》陸敏技