為了能更好地理解.NET基於角色的安全性,從一個最簡單的實例導入角色的應用。首先創建一個簡單的控制台程序,如代碼清單1-1所示。
代碼清單1-1 未添加角色驗證的程序
using System; namespace角色實例 { classProgram { static void Main(string[] args) { OutHello(); Console.Read(); } staticvoid OutHello() { Console.WriteLine("hello world!"); } } }
如代碼清單1-1,這個程序只有兩個方法:Main方法和OutHello方法,OutHello方法輸出“hello world!”,在Main方法中調用OutHello方法。運行程序會打印字符串“hello world!”。下面對這個簡單的程序做略微的修改,為它添加一些聲明,如代碼清單1-2所示。
代碼清單1-2 運行主體和主體權限要求的主體不一致的代碼
using System; using System.Security.Permissions; using System.Security.Principal; using System.Threading; namespace 角色實例 { class Program { static void Main(string[] args) { Thread.CurrentPrincipal = new WindowsPrincipal(WindowsIdentity.GetAnonymous()); try { OutHello(); } catch(SecurityException e) { Console.WriteLine(e.Message); } Console.Read(); } [PrincipalPermission(SecurityAction.Demand,Role="Administrators")] static void OutHello() { Console.WriteLine("hello world!"); } } }
在代碼清單1-2中,主要有三處變化:
1) 新添了三個名稱空間的引用,分別為System.Security.Permissions、System.Security.Principal和System.Threading。通過第4章的講解,我們對System.Security.Permissions名稱空間已經很熟悉了,這裡要使用其中的主體權限(PrincipalPermission)。System.Security.Principal是包含有關主體操作內容的名稱空間。System.Threading是有關線程操作的名稱空間。
2) 對於OutHello方法,聲明了PrincipalPermission權限,要求Administrators組成員才有權限執行此方法。
3) 對於Main方法,使用以下語句設置當前線程的主體為匿名用戶:
Thread.CurrentPrincipal = new WindowsPrincipal(WindowsIdentity.GetAnonymous())
下面來看代碼清單1-2的運行結果,如圖1-1所示。
圖1-1 代碼清單1-2運行結果
圖1-1表明,Main方法在調用OutHello方法時引發了SecurityException 異常。因為Main方法設置的主體為匿名用戶,而OutHello方法要求的是Administrators組用戶。下面把Main方法的執行線程設置為當前的Administrators用戶,再看看運行結果。修改後的Main方法如代碼清單1-3所示。
代碼清單1-3 運行主體和主體權限要求的主體一致的代碼
staticvoid Main(string[] args) { Thread.CurrentPrincipal = new System.Security.Principal.WindowsPrincipal(WindowsIdentity.GetCurrent()); try { OutHello(); } catch (SecurityException e) { Console.WriteLine(e.Message); } Console.Read(); }
代碼清單1-3設置了Main方法運行線程的主體為當前用戶,本書測試的當前用戶為Administrator(最高權限用戶,屬於Administrators組),此時的運行結果如圖1-2所示。
圖1-2 代碼清單1-3的運行結果
通過代碼清單1-1、代碼清單1-2和代碼請單1-3的對比,可以粗略地了解主體驗證的作用。在前面的代碼中采用了聲明式安全檢查的方法,同其他權限一樣,這裡仍然可以使用命令式安全檢查的方法來達到同樣的效果,對於聲明式和命令式安全檢查還不太熟悉的讀者可以回顧第4章的相關內容。修改後的代碼如代碼清單1-4所示。
代碼清單1-4 使用命令式安全檢查來指定主體權限
namespace 角色實例 { class Program { static void Main(string[] args) { Thread.CurrentPrincipal = new System.Security.Principal.WindowsPrincipal(WindowsIdentity.GetCurrent()); try { OutHello(); } catch (SecurityException e) { Console.WriteLine(e.Message); } Console.Read(); } static void OutHello() { new PrincipalPermission("", "Administrators").Demand(); Console.WriteLine("hello world!"); } } }
查看本欄目
代碼清單1-4中,通過創建PrincipalPermission類的實例的方式來標識當前方法的主體權限請求。使用PrincipalPermission類比使用PrincipalPermissioAtrribute進行聲明的方法更加靈活,可以充分運用它的多個重載方法。下面繼續修改Main方法,使用標識對象,如代碼清單1-5所示。
代碼清單1-5 使用標識
namespace 角色實例 { class Program { static void Main(string[] args) { GenericIdentity identity = new GenericIdentity("xuanhun"); string[] roles = new string[] { "Administrators" }; GenericPrincipal principal = new GenericPrincipal(identity, roles); AppDomain.CurrentDomain.SetThreadPrincipal(principal); OutHello(); Console.Read(); } static void OutHello() { new PrincipalPermission("xx", "Administrators").Demand(); Console.WriteLine("hello world!"); } } }
在代碼清單1-5的Main方法中,首先創建用戶自定義的標識對象identity,然後創建角色數組roles,並指定主體擁有的角色數組,最後設定當前應用程序域的主體。在OutHello方法中,要求標識名稱為xx;而在Main方法中指定的標識為xuanhun,運行程序將引發異常,如圖1-3所示。
圖1-3 標識不一致的運行結果
到目前為止,我們體驗了.NET的角色驗證,在感性上有了簡單的認識。更詳細內容,可以參考《.NET 安全揭秘》第五章。
作者:玄魂
出處:http://www.cnblogs.com/xuanhun/