.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 属性获得当前主体和标识对象,并调用其相关方法和属性进行进一步验证。

有关细节可参考 MSDN 文档,角色验证主要用于 ASP.NET 环境,雨痕将在后续 Blog 中做进一步说明。 

[转][.NET 基于角色安全性验证] 之一:基础知识相关推荐

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

    在开发过程中,我们需要做的事情包括: 1. 在 web.config 中设置 Forms 身份验证相关参数. 2. 创建登录页. 登录页中的操作包括: 1. 验证用户名和密码是否正确. 2. 创建身份 ...

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

    转载自:namelessml 原文链接:[完]基于Hadoop的数据仓库Hive 基础知识 Hive是基于Hadoop的数据仓库工具,可对存储在HDFS上的文件中的数据集进行数据整理.特殊查询和分析处 ...

  3. 数控机床手动编程能否用计算机验证,数控技术基础知识

    数控技术基础知识 数控技术和数控装备是制造工业现代化的重要基础.下面是YJBYS小编整理的数控技术基础知识,希望对你有帮助! 一.数控机床编程的方法 数控机床程序编制的方法有三种:即手工编程.自动编程 ...

  4. 基于动物标签识别的基础知识以及FDX-B协议与结构介绍。

    在此之前,要先了解一下动物识别标准. 1  国际动物识别标准介绍 ISO 11784:动物的射频识别--代码结构. ISO 11785:动物的射频识别--技术标准. ISO 11784和11785分别 ...

  5. 基于角色管理的系统访问控制

    引言(Introduction) 1.1. 关键词定义(Definitions) 有关定义说明如下: 安全管理:计算机技术安全管理的范围很广,可以包括网络安全性.数据安全性.操作系统安全性以及应用程序 ...

  6. 使用 Web Services Enhancements 2.0 的基于角色的安全性

    使用 Web Services Enhancements 2.0 的基于角色的安全性 简介 Microsoft .NET Framework 和 Microsoft ASP.NET 提供了许多保护代码 ...

  7. Survey Admin 示例:实现 Microsoft .NET 基于角色的安全性(转)

    适用于: Microsoft ASP.NET Microsoft .NET 框架 Microsoft Active Directory 或关系数据库(例如 Microsoft SQL Server?) ...

  8. .NET6之MiniAPI(九):基于角色的身份验证和授权

    身份验证是这样一个过程:由用户提供凭据,然后将其与存储在操作系统.数据库.应用或资源中的凭据进行比较. 在授权过程中,如果凭据匹配,则用户身份验证成功,可执行已向其授权的操作. 授权指判断允许用户执行 ...

  9. .Net Core实战之基于角色的访问控制的设计

    前言 上个月,我写了两篇微服务的文章:<.Net微服务实战之技术架构分层篇>与<.Net微服务实战之技术选型篇>,微服务系列原有三篇,当我憋第三篇的内容时候一直没有灵感,因此先 ...

最新文章

  1. jQuery 事件方法大全
  2. Delphi中预想不到的代码楼主zswang(伴水清清)(专家门诊清洁工)2002-05-16 14:20:38 在 Delphi / VCL组件开发及应用 提问
  3. android手势识别
  4. Android之三大图片缓存原理、特性对比
  5. 高内聚低耦合通俗理解_抱歉,请不要把“业务逻辑层”理解为“业务中台”
  6. 晶体封装越小esr越大_晶振
  7. JOSN的stringify()和parse()方法
  8. ELK下常见启动错误
  9. pymysql操作数据库
  10. 指数加权移动平均模型_常见收益模型
  11. springMVC对简单对象、Set、List、Map的数据绑定和常见问题(三)
  12. 凸优化第四章凸优化问题 4.5几何规划
  13. jQuery的文档操作
  14. [软件更新]暴风影音2009最新特别版光盘免费赠送(暴风门特别版)
  15. Ubuntu下 UltraEdit 破解/显色
  16. openwrt路由器samba拒绝访问
  17. 再读《谁说大象不能跳舞》
  18. 巴菲特:推荐给投资者的9本书(附下载链接)
  19. wia twain for java,c – 使用WIA或TWAIN扫描页面
  20. 密码学基础---椭圆曲线加密算法ECC(ELGamal Diffie-Hellman)

热门文章

  1. android动态调试防止,Android应用防止so注入防止动态调试参考代码
  2. 1157 全是1的最大子矩阵
  3. 埃氏筛法(求n以内有多少个素数)
  4. 求多个数最小公倍数和最大公约数
  5. 从此,懂一点CDMA
  6. linux中快速清空文件内容的方法
  7. CentOS7出现“FirewallD is not running”
  8. linux下如何挂载格式化内存卡,Linux下磁盘挂载格式化
  9. mysql blob图片_显示存储在mysql blob中的图像
  10. Tree树结构java实现