[.NET 基于角色安全性验证] 之一:基础知识

.NET 基于角色安全性验证的核心是主体(Principal)和标识(Identity)对象,其中主体负责角色或者组的验证,标识对象封装有关正在验证的用户或实体的信息。角色安全性验证通过生成可供当前线程使用的主体信息来支持授权,其中主体用关联的标识进行构造。

public interface IPrincipal
{
 // Methods
 bool IsInRole(string role);

 // Properties
 IIdentity Identity { get; }
}

public interface IIdentity
{
 // Properties
 string AuthenticationType { get; }
 bool IsAuthenticated { get; }
 string Name { get; }
}

在 .NET Framework 中提供了两组 Principal/Identity 类型,分别是基于 Windows 操作系统账户的 WindowsPrincipal/WindowsIdentity,以及用来进行自定义验证的 GenericPrincipal/GenericIdentity。

主体(Principal)对象在应用程序域(AppDomain)中绑定到调用上下文(CallContext)对象,缺省情况下,应用程序域会自动创建采取默认安全策略的 GenericPrincipal/GenericIdentity对象,同时主体(Principal)对象引用从创建线程自动复制到新线程的调用上下文(CallContext)中。我们可以通过 Thread.CurrentPrincipal 获得缺省主体(Principal)和标识(Identity)对象信息。

Console.WriteLine(Thread.CurrentPrincipal);
Console.WriteLine(Thread.CurrentPrincipal.Identity);

接下来,我们使用 WindowsPrincipal/WindowsIdentity 做一些简单的验证,同时为了进一步理解基于角色安全性验证的用途。

static void Test()
{
  Console.WriteLine("Test...");
}

static void Main(string[] args)
{
  Test();
}

我们修改上面这段代码,要求 Test() 方法必须是拥有管理员权限才能调用。

1. 我们使用 System.Security.Permissions.PrincipalPermissionAttribute 特性为 Test 方法加上角色验证标记,要求调用用户(Windows 操作系统登录用户)必须是 "Administrators" 组成员。

2. 在 Main 方法中设置线程的主体和标识对象。WindowsIdentity.GetCurrent() 用来获取当前登录用户的标识对象,如果登录用户属于 Adminstrators 组,则 Test() 方法正常调用,否则会触发 SecurityException 异常(我们可以使用 WindowsIdentity.GetAnonymous() 获取匿名用户标识对象来触发该异常)。

[PrincipalPermission(SecurityAction.Demand, Role = "Administrators")]
static void Test()
{
  Console.WriteLine("Test...");
}

static void Main(string[] args)
{
  Thread.CurrentPrincipal = new WindowsPrincipal(WindowsIdentity.GetCurrent());
  Test();
}

我们还可以使用其他的方法来做到这一点。

1. 使用 PrincipalPermission 对象替换 PrincipalPermissionAttribute,我们就可以使用动态权限验证,可以将用户名或者角色参数写入配置文件中。
2. 使用 AppDomain.CurrentDomain.SetThreadPrincipal 设置主体对象和 Thread.CurrentPrincipal 作用相同。我们还可以直接使用 AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal) 让系统自动使用当前登录用户名创建 WindowsPrincipal/WindowsIdentity。

static void Test()
{
  new PrincipalPermission(null, "Administrators").Demand();
  Console.WriteLine("Test...");
}

static void Main(string[] args)
{
  AppDomain.CurrentDomain.SetThreadPrincipal(new WindowsPrincipal(WindowsIdentity.GetCurrent()));
  Test();
}

或者

static void Test()
{
  new PrincipalPermission(null, "Administrators").Demand();
  Console.WriteLine("Test...");
}

static void Main(string[] args)
{
  AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
  Test();
}

上面的例子都是基于角色或者组的验证,当然我们还可以基于用户进行验证。

[PrincipalPermission(SecurityAction.Demand, Name="YUHEN//q.yuhen")]

new PrincipalPermission("YUHEN//q.yuhen", null).Demand();

当然,我们还可以同时用 role 和 name。PrincipalPermission 对象比 PrincipalPermissionAttribute 更加灵活,我们可以使用它进行多个权限的并集运算,以及进行 xml 转换等。

下面是使用 GenericPrincipal/GenericIdentity 改写的代码。

//[PrincipalPermission(SecurityAction.Demand, Name="q.yuhen", Role="admins")]
static void Test()
{
  new PrincipalPermission(null, "Administrators").Demand();
  Console.WriteLine("Test...");
}

static void Main(string[] args)
{
  // 创建自定义用户标识对象。
  GenericIdentity identity = new GenericIdentity("q.yuhen");
  
  // 创建主体对象,并指定所拥有的角色数组。
  string[] roles = new string[] { "admins" };
  GenericPrincipal principal = new GenericPrincipal(identity, roles);
  
  // 设定主体。
  AppDomain.CurrentDomain.SetThreadPrincipal(principal);
  
  Test();
}

除了使用上述方法外,某些时候我们并不希望触发 SecurityException 异常,我们希望能给出另外的执行策略,那么可以直接使用 Principal.InRole 以及 Identity.Name 了。

static void Test()
{
  if (Thread.CurrentPrincipal.IsInRole("admins") && Thread.CurrentPrincipal.Identity.Name == "q.yuhen")
  {
    Console.WriteLine("Test...");
  }
  else
  {
    Console.WriteLine("您没有执行权限!");
  }
}

总结一下,基于角色的安全检查有三种方法。

1. 使用命令式安全检查。该方法主要是通过 PrincipalPermission.Demand() 方法进行。
2. 使用声明性安全检查。通过 PrincipalPermissionAttribute 特性指定运行所需角色和用户名。
3. 直接访问 Principal 对象。访问 Thread.CurrentPrincipal 属性获得当前主体和标识对象,并调用其相关方法和属性进行进一步验证。
 

时间: 2024-11-10 01:08:42

[.NET 基于角色安全性验证] 之一:基础知识的相关文章

[.NET 基于角色安全性验证] 之四:ASP.NET 2.0 成员资格和角色管理授权

从严格意义上来说,ASP.NET 2.0 的成员资格.角色管理授权和 .NET 角色安全性没有多大关系.只不过,Microsoft 替我们完成了一些原本需要我们自己进行的工作而已. 在这两种新的技术中使用的"提供程序模型"倒是值得我们好好学习一下,因为这个 IoC 概念非常相似. 成员资格 成员资格提供了通用的用户管理功能,诸如注册.登录.找回密码等,加上与之配套的可视化控件,我们"几乎"不用在编写额外的代码就可以工作.实际上真是如此吗?MemebershipUse

[.NET 基于角色安全性验证] 之三:ASP.NET Forms 身份验证

在开发过程中,我们需要做的事情包括: 1. 在 web.config 中设置 Forms 身份验证相关参数.2. 创建登录页. 登录页中的操作包括: 1. 验证用户名和密码是否正确.2. 创建身份验证票证对象.3. 将身份验证票证对象加密成字符串,写入 Cookies.4. 重定向到原始请求 URL. 1. 简单演示 web.config <?xml version="1.0"?><configuration>  <system.web>    &l

[.NET 基于角色安全性验证] 之五:跨应用程序进行 Forms 身份验证

ASP.NET 支持在分布式环境中(跨单个服务器上的多个应用程序或在网络场中)进行 Forms 身份验证.如果启用了跨多个 ASP.NET 应用程序的 Forms 身份验证,则当用户在应用程序之间切换时,不需要对他们重新进行身份验证. 要配置跨应用程序的 Forms 身份验证,请在 forms 和 machineKey 配置节中设置若干属性,以便值对于参与共享 Forms 身份验证的所有应用程序都是相同的. 下面的示例演示了 Web.config 文件的 Authentication 节.除非另

详解JavaScript中的表单验证_基础知识

 表单验证用于发生在服务器,客户端已经输入所有必要的数据,然后按下提交按钮之后.如果一些已被输入的客户端的数据的已在错误形式或者被简单地丢失,则服务器将必须的所有数据发送回客户端,并请求的形式以正确的信息重新提交.这是一个漫长的过程,会增加服务器负担. JavaScript中,提供了一种方法将其发送到web服务器之前验证客户端的计算机上的形式的数据.表单验证通常执行两种方式.     基本验证 - 首先,该表必须进行检查,以确保数据输入的需要将其每一个表单字段.这将通过表格的每个字段只需要循环,

easyui validatebox验证_基础知识

<html xmlns="http://www.w3.org/1999/xhtml"> <head> <script src="easyui1.2.4/jquery-1.6.min.js" type="text/javascript"></script> <script src="easyui1.2.4/jquery.easyui.min.js" type="te

基于Hadoop的数据仓库Hive基础知识

Hive是基于Hadoop的数据仓库工具,可对存储在HDFS上的文件中的数据集进行数据整理.特殊查询和分析处理,提供了类似于SQL语言的查询语言–HiveQL,可通过HQL语句实现简单的MR统计,Hive将HQL语句转换成MR任务进行执行. 一.概述 1-1 数据仓库概念 数据仓库(Data Warehouse)是一个面向主题的(Subject Oriented).集成的(Integrated).相对稳定的(Non-Volatile).反应历史变化(Time Variant)的数据集合,用于支持

Asp.net中基于角色验证授权

Asp.net的身份验证有有三种,分别是"Windows | Forms | Passport",其中又以Forms验证用的最多,也最灵活.Forms 验证方式对基于用户的验证授权提供了很好的支持,可以通过一个登录页面验证用户的身份,将此用户的身份发回到客户端的Cookie,之后此用户再访问这个web应用就会连同这个身份Cookie一起发送到服务端.服务端上的授权设置就可以根据不同目录对不同用户的访问授权进行控制了.问题来了,在实际是用中我们往往需要的是基于角色,或者说基于用户组的验证

.NET框架中基于角色的安全性(1)

.net框架|安全|安全性 在过去的相当长一段时间内,计算机及信息犯罪的比例正在逐渐升高.美国联邦调查局的计算机安全组织在2001年的研究调查中发现85%企业的企业安全受到侵害.在对这些企业进行调查之后提出的财物损失报告中指出,合计损失为3亿7千7百万美元,比起2000年的2亿6千5百万美金增加了42%.由此可清楚的看出,计算机及信息犯罪的发生次数越来越频繁,其所造成的损失也越来越大,另外,犯罪的手段也越来越丰富,令企业安全人员防不胜防.因此企业必须有所行动来保护有价值的信息资产.自然而然的,安

基于角色的安全性编程入门示例

为了能更好地理解.NET基于角色的安全性,从一个最简单的实例导入角色的应用.首先创建一个简单的控制台程序,如代码清单1-1所示. 代码清单1-1  未添加角色验证的程序 using System; namespace角色实例 { classProgram { static void Main(string[] args) { OutHello(); Console.Read(); } staticvoid OutHello() { Console.WriteLine("hello world!&