模拟在WCF中的应用
在《模拟(Impersonation)与委托(Delegation)》一文中,我们对模拟和委托这两个概念以及相关编程实现进行了详细说明。如果将模拟使用在WCF上面,就意味着WCF可以模拟客户端身份(而不是启动寄宿进程的Windows帐号)执行服务操作。这篇文章主要介绍WCF关于模拟的编程。
一、命令式模拟编程
如果我们有一个具有模拟级别为Impersonation或者Delegation的WindowsIdentity,我们就可以通过调用其Impersonate对其进行身份模拟。在采用WCF认证的情况下,我们可以通过当前ServiceSecurityContext的WindowsIdentity或者PrimaryIdentity获取到代码认证客户端的WindowsIdentity对象,那么在服务操作中模拟客户端身份就和简单了。这种在服务操作实现中通过编程的方式实现身份模式可以将服务操作的部分逻辑在模拟的客户端身份下执行。
1: using (WindowsImpersonationContext context = ServiceSecurityContext.Current.WindowsIdentity.Impersonate())
2: {
3: //在模拟上下文中执行的操作
4: }
二、声明式模拟编程
如果你希望整个操作都在模拟上下文中执行,你可以采用声明式的模拟编程。具体来说,你只需要在需要进行模拟的服务操作方法上应用OperationBehaviorAttribute特性,并指定相应的模拟选项即可。
1: [AttributeUsage(AttributeTargets.Method)]
2: public sealed class OperationBehaviorAttribute : Attribute, IOperationBehavior
3: {
4: //其他成员
5: public ImpersonationOption Impersonation { get; set; }
6: }
7: public enum ImpersonationOption
8: {
9: NotAllowed,
10: Allowed,
11: Required
12: }
通过OperationBehaviorAttribute的Impersonation属性指定模拟选项通过枚举ImpersonationOption表示。定义在ImpersonationOption的三个枚举项NotAllowed、Allowed和Required分别表示的含义如下。
- NotAllowed:不允许模拟客户端身份,这是默认值;
- Allowed:在身份模拟条件满足条件允许模拟客户端身份;
- Required:强制模拟客户端身份。这要求强制采用Windows认证,如果采用非Windows认证,会抛出异常。
此外,如果你要求服务的所有操作均强制采用身份模拟,你可以通过编程或者配置将ServiceAuthorizationBehavior的ImpersonateCallerForAllOperations属性设置成true。但是在这种情况下,如果该服务具有任何模拟选项被设置成NotAllowed的服务操作,服务在寄宿过程中会抛出InvalidationOperationException异常。
1: public sealed class ServiceAuthorizationBehavior : IServiceBehavior
2: {
3: //其他成员
4: public bool ImpersonateCallerForAllOperations { get; set; }
5: }
三、设置模拟级别
在采用Windows认证的情况下,服务可以在成功认证后可以获取代表客户端身份的WindowsIdentity对象。但是服务端是否可以根据WindowsIdentity获取客户端身份信息,是否可以模拟客户端身份访问某些安全资源,这取决于该WindowsIdentity的模拟级别。
身份模拟密切地关系到被模拟身份代表的用户的安全,所以模拟级别应该通过客户端自行控制。在WCF安全体系中,该模拟级别是在客户端提供的Windows凭证中指定。如下面的代码所示,表示客户端Windows凭证的WindowsClientCredential类型中,具有一个类型为TokenImpersonationLevel枚举的AllowedImpersonationLevel属性,用以指定模拟级别。该属性的默认值为None,实际上代表的等级是Identification。
1: public sealed class WindowsClientCredential
2: {
3: //其他成员
4: public TokenImpersonationLevel AllowedImpersonationLevel { get; set; }
5: }
- 利用TensorFlow生成图像标题
- 保存并加载您的Keras深度学习模型
- 简单、通用的JQuery Tab实现
- Dubbo源码解析 - 远程暴露
- 使用FastText(Facebook的NLP库)进行文本分类和word representatio...
- 声音分类的迁移学习
- 【死磕Java并发】—– J.U.C之AQS:CLH同步队列
- 使用Python完成你的第一个学习项目
- CA,给了数据库,给了机器,为啥也扩不了容?
- 如何使用Anaconda设置机器学习和深度学习的Python环境
- MQ,互联网架构解耦神器
- 预测随机机器学习算法实验的重复次数
- 服务化了,没想到耦合更加严重?
- 如何在Python中扩展LSTM网络的数据
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 缓冲流---为字节流和字符流复制文件增加缓冲流
- 字符流---输入输出与复制文本文件
- Spring 中的几个 PostProcessor 的区别与联系
- Spring 中基于注解的事务控制及原理分析
- Spring 中根据环境切换配置 @Profile
- Spring 中的属性赋值
- Spring 中控制 Bean 生命周期的几种方式及 BeanPostProcessor 执行原理
- Spring 中的 @Import 注解及向容器中添加 Bean 的几种方式
- Spring 注解开发之 @Conditional
- JDBC 技术应用实践:网上书城后台管理系统
- 思科模拟器:路由器基本配置
- 思科模拟器:实验五——高级路由实验
- 从零开始重新认识 SpringMVC
- 字节跳动Android实习面试凉凉经,两轮面试我被完虐了...
- 高效、简单、方便管理与维护的开源运维工单系统