[WCF权限控制]利用WCF自定义授权模式提供当前Principal[原理篇]
2011-07-07 22:07
986 查看
在《通过扩展自行实现服务授权》一文中,我通过自定义CallContextInitializer的方式在操作方法之前之前根据认证用户设置了当前线程的安全主体,从而实现授权的目的。实际上,WCF的安全体系本就提供相应的扩展,使你能够自由地实现安全主体的提供方式。具体来说,安全主体的提供可以通过自定AuthorizationPolicy或者ServiceAuthorizationManager来实现。
[/code]
如果我们需要通过自定义的方式来提供安全主体,我们只需要通过实现IAuthorizationPolicy接口创建自定义的AuthorizationPolicy,并在Evaluate方法中将创建安全主体对象添加到EvaluationContext的Properties字典中即可。在该字典中,用于存放安全主体条目对应的键值为“Principal”。
[/code]
那么自定义的AuthorizationPolicy通过怎样的方式被应用到WCF的授权运行时呢?这还是要借助于我们已经很熟悉的服务行为ServiceAuthorizationBehavior。如下面给出的代码片断所示,ServiceAuthorizationBehavior具有一个类型为ReadOnlyCollection<IAuthorizationPolicy> 的ExternalAuthorizationPolicies属性,表示自定义AuthorizationPolicy的集合。
[/code]
你可以通过编程的方式将自定义的AuthorizationPolicy添加到ServiceAuthorizationBehavior的ExternalAuthorizationPolicies集合中,也可以通过配置指定自定义AuthorizationPolicy的类型。如下面给出的配置片断所示,ServiceAuthorizationBehavior的ExternalAuthorizationPolicies集合对应的配置节点为<serviceAuthorization>/<authorizationPolicies>。
[/code]
[/code]
当ServiceAuthorizationBehavior的PrincipalPermissionMode被设置成Custom的情况下,被设置的当前安全主体实际上是通过当前服务安全上下文(ServiceSecurityContext)获取的。具体来说,ServiceSecurityContext具有一个表示授权信息的AuthorizationContext对象。和EvaluationContext一样,AuthorizationContext也具有一个字典类型的Properties属性。实际上,通过AuthorizationPolicy添加到EvaluationContext中的属性,最终都会被转移到当前AuthorizationContext的Properties属性中。
[/code]
所以只要我们能够在WCF从当前AuthorizationContext获取安全主体之前对其进行初始化,整个基于安全主体的授权体系就能正常运作,而这个工作可以通过自定义ServiceAuthorizationManager来实现。一般来讲,我们只需通过继承ServiceAuthorizationManager,重写虚方法CheckAccessCore进行安全主体的初始化。
[/code]
自定义的ServiceAuthorizationManager最终还是通过ServiceAuthorizationBehavior这个服务行为应用到WCF授权框架体系中。如下面给出的代码片断所示,在ServiceAuthorizationBehavior中依然具有相应属性定义的。而在ServiceAuthorizationBehavior的配置节中,ServiceAuthorizationManager对应的配置属性为serviceAuthorizationManager,你可以通过该配置属性将设置自定义ServiceAuthorizationManager的类型。
[/code]
如果两种默认的安全主体权限模式(UseWindowsGroup和UseAspNetRoles)不能满足你的要求,你需要自定义安全主体提供方式,自定义AuthorizationPolicy或者ServiceAuthorizationManager不失为一个很好的解决方案。为了让你对此有个深刻的认识,在《下篇》中我们提供一个完整的实例。
[WCF权限控制]利用WCF自定义授权模式提供当前安全主体[原理篇]
[WCF权限控制]利用WCF自定义授权模式提供当前安全主体[实例篇]
一、AuthorizationPolicy
在WCF安全应用编程接口中,所有的AuthorizationPolicy实现了IAuthorizationPolicy接口。如下面的代码所示,IAuthorizationPolicy继承自IAuthorizationComponent接口,本身具有一个ClaimSet类型的Issuer属性和一个Evaluate方法。关于ClaimSet,我们会在后续的部分继续介绍,这里我们只需要关注Evaluate方法。该方法的第一个参数的类型为System.IdentityModel.Policy.EvaluationContext,它具有一个字典类型的只读属性Properties。[code] public interface IAuthorizationPolicy : IAuthorizationComponent { bool Evaluate(EvaluationContext evaluationContext, ref object state); ClaimSet Issuer { get; } } public abstract class EvaluationContext { //其他成员 public abstract IDictionary<string, object> Properties { get; } }
[/code]
如果我们需要通过自定义的方式来提供安全主体,我们只需要通过实现IAuthorizationPolicy接口创建自定义的AuthorizationPolicy,并在Evaluate方法中将创建安全主体对象添加到EvaluationContext的Properties字典中即可。在该字典中,用于存放安全主体条目对应的键值为“Principal”。
[code] Public class CustomAuthorizationPolicy:IAuthorizationPolicy { //其他成员 bool Evaluate(EvaluationContext evaluationContext, ref object state) { //其他操作 evaluationContext. Properties[“Principal”] = customPrincipal; return true; } }
[/code]
那么自定义的AuthorizationPolicy通过怎样的方式被应用到WCF的授权运行时呢?这还是要借助于我们已经很熟悉的服务行为ServiceAuthorizationBehavior。如下面给出的代码片断所示,ServiceAuthorizationBehavior具有一个类型为ReadOnlyCollection<IAuthorizationPolicy> 的ExternalAuthorizationPolicies属性,表示自定义AuthorizationPolicy的集合。
[code] public sealed class ServiceAuthorizationBehavior : IServiceBehavior { //其他成员 public ReadOnlyCollection<IAuthorizationPolicy> ExternalAuthorizationPolicies { get; set; } }
[/code]
你可以通过编程的方式将自定义的AuthorizationPolicy添加到ServiceAuthorizationBehavior的ExternalAuthorizationPolicies集合中,也可以通过配置指定自定义AuthorizationPolicy的类型。如下面给出的配置片断所示,ServiceAuthorizationBehavior的ExternalAuthorizationPolicies集合对应的配置节点为<serviceAuthorization>/<authorizationPolicies>。
[code] <configuration> <system.serviceModel> <behaviors> <serviceBehaviors> <behavior name="useCustomAuthorization"> <serviceAuthorization principalPermissionMode="Custom"> <authorizationPolicies > <add policyType="AuthorizationPolicyType1" /> <add policyType="AuthorizationPolicyType2" /> ... </authorizationPolicies> </serviceAuthorization> <serviceDebug includeExceptionDetailInFaults="true"/> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel> </configuration>
[/code]
二、ServiceAuthorizationManager
在ServiceAuthorizationBehavior选择Custom安全主体权限模式的情况下,除了自定义AuthorizationPolicy,你还可以通过自定义ServiceAuthorizationManager来提供当前的安全主体。下面给出了ServiceAuthorizationManager的定义,从中我们可以看出它具有两个CheckAccess方法用于实现授权。方法的返回值表示当前请求的服务操作是否被授权指定。实际上最终的授权判断实现在受保护方法CheckAccessCore中,并且在ServiceAuthorizationManager中该方法直接返回True。[code] public class ServiceAuthorizationManager { //其他成员 public virtual bool CheckAccess(OperationContext operationContext); public virtual bool CheckAccess(OperationContext operationContext, ref Message message); protected virtual bool CheckAccessCore(OperationContext operationContext); }
[/code]
当ServiceAuthorizationBehavior的PrincipalPermissionMode被设置成Custom的情况下,被设置的当前安全主体实际上是通过当前服务安全上下文(ServiceSecurityContext)获取的。具体来说,ServiceSecurityContext具有一个表示授权信息的AuthorizationContext对象。和EvaluationContext一样,AuthorizationContext也具有一个字典类型的Properties属性。实际上,通过AuthorizationPolicy添加到EvaluationContext中的属性,最终都会被转移到当前AuthorizationContext的Properties属性中。
[code] public class ServiceSecurityContext { //其他成员 public AuthorizationContext AuthorizationContext { get; } } public abstract class AuthorizationContext : IAuthorizationComponent { //其他成员 public abstract IDictionary<string, object> Properties { get; } }
[/code]
所以只要我们能够在WCF从当前AuthorizationContext获取安全主体之前对其进行初始化,整个基于安全主体的授权体系就能正常运作,而这个工作可以通过自定义ServiceAuthorizationManager来实现。一般来讲,我们只需通过继承ServiceAuthorizationManager,重写虚方法CheckAccessCore进行安全主体的初始化。
[code] public class CustomServiceAuthorizationManager : ServiceAuthorizationManager { protected override bool CheckAccessCore(OperationContext operationContext) { //其他操作 AuthorizationContext authorizationContext = operationContext.ServiceSecurityContext.AuthorizationContext; authorizationContext.Properties["Principal"] = customPrincipal; return true; } }
[/code]
自定义的ServiceAuthorizationManager最终还是通过ServiceAuthorizationBehavior这个服务行为应用到WCF授权框架体系中。如下面给出的代码片断所示,在ServiceAuthorizationBehavior中依然具有相应属性定义的。而在ServiceAuthorizationBehavior的配置节中,ServiceAuthorizationManager对应的配置属性为serviceAuthorizationManager,你可以通过该配置属性将设置自定义ServiceAuthorizationManager的类型。
[code] public sealed class ServiceAuthorizationBehavior: IServiceBehavior { //其他成员 public ServiceAuthorizationManager ServiceAuthorizationManager { get; set; } }
[/code]
如果两种默认的安全主体权限模式(UseWindowsGroup和UseAspNetRoles)不能满足你的要求,你需要自定义安全主体提供方式,自定义AuthorizationPolicy或者ServiceAuthorizationManager不失为一个很好的解决方案。为了让你对此有个深刻的认识,在《下篇》中我们提供一个完整的实例。
[WCF权限控制]利用WCF自定义授权模式提供当前安全主体[原理篇]
[WCF权限控制]利用WCF自定义授权模式提供当前安全主体[实例篇]
相关文章推荐
- [WCF权限控制]利用WCF自定义授权模式提供当前Principal[实例篇]
- [WCF权限控制]WCF自定义授权体系详解[原理篇]
- [WCF权限控制]WCF的三种授权模式
- [WCF权限控制]通过扩展自行实现服务授权[提供源码下载]
- [WCF权限控制]WCF自定义授权体系详解[实例篇]
- [WCF权限控制]从两个重要的概念谈起:Identity与Principal[上篇]
- [WCF权限控制]ASP.NET Roles授权[上篇]
- WCF4.0 —— Routing Service 自定义Filter控制访问权限
- [WCF权限控制]基于Windows用户组的授权方式[上篇]
- BAT-把当前用户以管理员权限运行(用户帐户控制:用于内置管理员帐户的管理员批准模式)
- [WCF权限控制]基于Windows用户组的授权方式[下篇]
- SpringSecurity 3.2入门(10)自定义权限控制认证及授权的过程
- [WCF权限控制]ASP.NET Roles授权[下篇]
- [WCF权限控制]ASP.NET Roles授权[上篇]
- [WCF权限控制]ASP.NET Roles授权[下篇]
- 认证鉴权与API权限控制在微服务架构中的设计与实现:授权码模式
- [WCF权限控制]基于Windows用户组的授权方式
- 利用struts2拦截器加自定义注解实现权限控制
- JAVAWEB开发之Servlet3.0新特性的使用以及注解的详细使用和自定义注解的方法、动态代理的使用、利用动态代理实现细粒度的权限控制以及类加载和泛型反射
- [WCF权限控制]从两个重要的概念谈起:Identity与Principal[下篇]