[WCF权限控制]基于Windows用户组的授权方式[上篇]

Windows用户组安全主体权限模式,顾名思义,就是将利用Windows安全系统将对应的Windows帐号所在的用户组作为该用户权限集的授权方式。认证和授权密不可分,但是对于认证和授权在WCF安全体系中的实现来说,它们则是相对独立的。认证属于安全传输的范畴,是在信道层实现的,而授权则是在服务模型层实现的。但是对于基于Windows用户组的授权来说,最终体现出来的授权行为却和采用何种认证具有密切的关系。

一、Windows用户组授权与认证的关系

无论是对于基于Windows用户组还是基于ASP.NET Roles提供程序的授权,最终都体现在创建相应的安全主体,并将其附加到当前线程上。对于Windows用户组模式来说,有一点是肯定的:不论采用何种客户端凭证类型以及认证模式,最终建立的安全主体都是一个WindowsPrincipal,并且这个WindowsPrincipal对应的安全身份是一个WindowsIdentity。但是该WindowsPrincipal的Identity能否正确地反映被认证后的用户,以及其本身能够正确反映该认证用户的权限,就和认证有密切的关系。

具体来说,当你选择了Windows用户组安全主体权限模式,只有在采用Windows认证的情况下最终生成的安全主体才能正确地反映被认证的用户。这里的Windows认证包括如下三种情况:

  • 客户端凭证为Windows凭证;
  • 客户端凭证为用户名/密码凭证,并采用Windows认证模式;
  • 客户端凭证为X.509证书凭证,并允许与Windows帐号进行映射。

在其他情况下,最终被创建的是一个“空”的WindowsPrincipal。这个空的WindowsPrincipal不仅仅体现在具有一个“空”的权限集,而且其内部的WindowsIdentity也为“空”。该WindowsIdentity具有如下面列表所示的属性。

  • Name:空字符串
  • AuthenticationType: 空字符串
  • IsAuthenticated:False
  • Groups:Null
  • IsAnonymous:True
  • IsGuest:False
  • IsSystem:False

在非Windows认证的情况下,即使存在着一个与认证用户一致的Windows帐号,WCF授权系统都不会基于该Windows帐号来创建最终的WindowsPrincipal。举个例子,假设服务寄宿端所在的域中具有一个用户叫做“张三”,并且存在于当前机器的管理员(Administrators)用户组中。现在我们对某个服务操作进行授权,要求必须在具有管理员权限才能被调用。在进行服务寄宿的时候,终结点的绑定采用用户名/密码作为客户端凭证,并选择Membership认证模式。在认证成功的情况下,被授权的服务操作也是不能被正常调用的。

通过前面一篇文章的介绍,我们知道了WCF采用怎样的授权的方式通过ServiceAuthorizationBehavior这一服务行为来控制。所以针对授权的编程主要就体现在对该服务行为的设置。对于Windows用户组授权来说,我们只需要将ServiceAuthorizationBehavior的PrincipalPermissionMode属性设置成PrincipalPermissionMode.UseWindowsGroups即可。

二、ServiceAuthorizationBehavior服务行为的设置

既然ServiceAuthorizationBehavior是一个服务行为,我们只需要通过编程或者配置的方式将该服务行为添加到当前服务的行为列表中就可以了。你可以按照下面的编程方式让寄宿的服务采用基于Windows用户组授权模式。

   1: using (ServiceHost host = new ServiceHost(typeof(CalculatorService)))
   2: {
   3:     ServiceAuthorizationBehavior behavior = host.Description.Behaviors.Find<ServiceAuthorizationBehavior>();
   4:     if (null == behavior)
   5:     {
   6:         behavior = new ServiceAuthorizationBehavior();
   7:         host.Description.Behaviors.Add(behavior);
   8:     }
   9:     behavior.PrincipalPermissionMode = PrincipalPermissionMode.UseWindowsGroups;
  10:     host.Open();
  11:     //...
  12: }

此外在ServiceHost你也可以通过ServiceHost的只读属性Authorization得到这个ServiceAuthorizationBehavior对象。如下面的代码片断所示,该属性实际上是定义在ServiceHost的基类ServiceHostBase中。

   1: public abstract class ServiceHostBase
   2: {
   3:     //其他成员
   4:     public ServiceAuthorizationBehavior Authorization { get; }
   5: }

在读取该属性的时候,如果当前服务描述中的服务行为列表中找不到ServiceAuthorizationBehavior,系统会自动创建一个ServiceAuthorizationBehavior对象并添加到服务行为列表中。所以对于上面的这段服务寄宿代码实际和下面是完全等效的。

   1: using (ServiceHost host = new ServiceHost(typeof(CalculatorService)))
   2: {    
   3:     host.Authorization.PrincipalPermissionMode = PrincipalPermissionMode.UseWindowsGroups;
   4:     host.Open();
   5:     //...
   6: }

我们依然推荐采用配置的方式进行授权模式的设置。而下面一段配置和上面的代码在作用上是等效的。

   1: <configuration>
   2:   <system.serviceModel>    
   3:     <services>
   4:       <service name="Artech.WcfServices.Services.CalculatorService" behaviorConfiguration="UseWindowsGroupsAuthorization">
   5:         <endpoint address="http://127.0.0.1/calculatorservice" binding="ws2007HttpBinding" contract="Artech.WcfServices.Contracts.ICalculator"/>
   6:       </service>
   7:     </services>
   8:     <behaviors>
   9:       <serviceBehaviors>
  10:         <behavior  name="UseWindowsGroupsAuthorization">
  11:           <serviceAuthorization principalPermissionMode="UseWindowsGroups"/>
  12:         </behavior>
  13:       </serviceBehaviors>
  14:     </behaviors>
  15:   </system.serviceModel>
  16: </configuration>

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏开源优测

工具篇 - JMeter组件手册04

前言 在jmeter中提供了一系列的不同的组件,每一种组件都提供了某类功能的实现,用于支持性能测试的实施。 请看下图,jmeter的核心组件构成。 ? 学习、研...

39380
来自专栏乐沙弥的世界

RAC 环境下的重要参数

    Oracle 数据库启动时会根据参数文件中提供的相关参数启动Oracle实例。这些参数包括数据库名字、sga,pga的分配,控制文件的位置,undo,p...

7710
来自专栏马洪彪

Java设计模式(三)单例模式

一、场景描述 在采集到仪器数据后,需要将数据发送到lims系统中,通过调用lims系统服务实现数据的上传。 在仪器数据采集组件中实现lims系统服务代理,该代理...

36160
来自专栏运维小白

4.3/4.4 磁盘分区

添加虚拟磁盘 第一步,选择虚拟机中的“设置” ? 第二步,选择“添加硬盘” ? 第三步,选择_SCSI (推荐) # 保持默认 ? 第四...

26350
来自专栏linux驱动个人学习

解析Linux中的VFS文件系统之文件系统的注册(二)

继上一篇文章:https://cloud.tencent.com/developer/article/1053882 3. 文件系统的注册 这里的文件系统是指可...

36660
来自专栏码匠的流水账

nginx proxy cache配置参数解读

本文主要解析一下nginx ngx_http_proxy_module中的cache相关配置参数。

20010
来自专栏Python中文社区

flask 项目搭建及配置分享

作者:Tom .Lee,GitHub ID:tomoncle ,Web and cloud computing developer, Java, Golang,...

20540
来自专栏深度学习自然语言处理

有关vi(vim)的常用命令

导读 vi(vim)是上Linux非常常用的编辑器,很多Linux发行版都默认安装了vi(vim)。vi(vim)命令繁多但是如果使用灵活之后将会大大提高效率。...

33460
来自专栏用户画像

程序中断和调用子程序有何区别

1)调用子程序发生的时间是已知的和固定的,即在主程序的调用指令(CALL)执行时发生主程序调用子程序过程,调用指令所在位置是已知的和固定的;而中断过程发生的时间...

12720
来自专栏学习力

《Java从入门到放弃》框架入门篇:Struts2的基本访问方式(二)

17440

扫码关注云+社区

领取腾讯云代金券