分类: 嵌入式
2012-06-23 18:24:06
为了能更好地理解.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 安全揭秘》第五章。