建議121:爲應用程序設定運行權限

建議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個建議》陸敏技

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章