WCF进阶:扩展bindingElementExtensions支持对称加密传输
前面两篇文章WCF进阶:将编码后的字节流压缩传输和WCF 进阶: 对称加密传输都是实现了自定义编码,那两个例子中托管服务或者客户端调用都采用的代码实现,WCF更友好的方式是在app.config或web.config来配置服务的运行和调用,本文是介绍如何在配置文件中配置自定义的BindingElement。
上文WCF 进阶: 对称加密传输中我们实现了一个自定义的BindingElement:CryptEncodingBindingElement,它是一个MessageEncodingBindingElement,在宿主程序中,我们通过代码的方式将其添加到CustomBinding中去,方法为:
ICollection<BindingElement> bindingElements = new List<BindingElement>();
HttpTransportBindingElement httpBindingElement = new HttpTransportBindingElement();
string key = "JggkieIw7JM=";
string iv = "XdTkT85fZ0U=";
CryptEncodingBindingElement textBindingElement = new CryptEncodingBindingElement(new BinaryMessageEncodingBindingElement(), key, iv);
bindingElements.Add(textBindingElement);
bindingElements.Add(httpBindingElement);
CustomBinding bind = new CustomBinding(bindingElements);
如果是缺省的BindingElement,如TextMessageEncodingElement,HttpTransportElement,ReliableSessionElement,SecurityElement都可以像如下这样的方式进行配置:
<bindings>
<customBinding>
<binding name="myBinding">
<textMessageEncoding/>
<reliableSession/>
<security/>
<httpTransport/>
</binding>
</customBinding>
</bindings>
如果要想让我们自定义的BindingElement和上面的一样享受同等待遇的话,我们需要再额外做一些事情,那就是重载BindingElementExtensionElement,在.Net中扩展配置的基类为:ConfigurationElement,它定义声明了一些扩展配置的属性和方法,为了方便WCF重载了ConfigurationElement形成了ServiceModelExtensionElement,而为了进一步的方便扩展BindingElement,又提供了BindingElementExtensionElement的基类,创建自定义的BindingElementExtension,只需要重载BindingElementExtensionElement三个方法:
using System;
using System.ServiceModel.Channels; namespace System.ServiceModel.Configuration
{
// 摘要:
// 为使用计算机或应用程序配置文件中的自定义 System.ServiceModel.Channels.BindingElement 实现提供支持。
public abstract class BindingElementExtensionElement : ServiceModelExtensionElement
{
// 摘要:
// 初始化 System.ServiceModel.Configuration.BindingElementExtensionElement 类的新实例。
protected BindingElementExtensionElement(); // 摘要:
// 在派生类中重写时,获取表示自定义绑定元素的 System.Type 对象。
//
// 返回结果:
// 一个表示自定义绑定类型的 System.Type 对象。
public abstract Type BindingElementType { get; } // 摘要:
// 将指定绑定元素的内容应用到此绑定配置元素。
//
// 参数:
// bindingElement:
// 一个绑定元素。
//
// 异常:
// System.ArgumentNullException:
// bindingElement 为 null。
public virtual void ApplyConfiguration(BindingElement bindingElement);
//
// 摘要:
// 在派生类中重写时,返回一个自定义绑定元素对象。
//
// 返回结果:
// 一个自定义 System.ServiceModel.Channels.BindingElement 对象。
protected internal abstract BindingElement CreateBindingElement();
//
// 摘要:
// 使用指定绑定元素的内容来初始化此绑定配置节。
//
// 参数:
// bindingElement:
// 一个绑定元素。
protected internal virtual void InitializeFrom(BindingElement bindingElement);
}
}
public abstract Type BindingElementType { get; } 这个属性中只需要返回自定义类的类型,protected internal abstract BindingElement CreateBindingElement()的重载就是在这创建需要的自定义BindingElement,如果自定义的BindingElement有额外的属性或者参数,我们可以还可以通过创建带有ConfigurationPropertyAttribute的属性来指定。这个是.Net配置中的通性。在我们的需求中,需要一个CryptEncodingBindingElement实例,而CryptEncodingBindingElement带有三个参数:InnerMessageEncodingBindingElement,Key,IV。分析到这,我们的自定义BindingElement配置扩展类就成形了,代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel.Configuration;
using System.Configuration; namespace RobinLib
{
public class CryptEncodingBindingElementConfiguration : BindingElementExtensionElement
{
public override void ApplyConfiguration(System.ServiceModel.Channels.BindingElement bindingElement)
{
CryptEncodingBindingElement bind = bindingElement as CryptEncodingBindingElement;
if (InnerMessageEncoding.ToLower() == "text")
{
bind.InnerMessageEncodingBindingElement = new System.ServiceModel.Channels.TextMessageEncodingBindingElement();
}
else if (InnerMessageEncoding.ToLower() == "binary")
{
bind.InnerMessageEncodingBindingElement = new System.ServiceModel.Channels.BinaryMessageEncodingBindingElement();
}
else if (InnerMessageEncoding.ToLower() == "mtom")
{
bind.InnerMessageEncodingBindingElement = new System.ServiceModel.Channels.MtomMessageEncodingBindingElement(); }
bind.Key = Key;
bind.IV = IV;
base.ApplyConfiguration(bindingElement);
} [ConfigurationProperty("innerMessageEncoding",DefaultValue="text")]
public string InnerMessageEncoding
{
get
{
return base["innerMessageEncoding"] as string;
}
set
{
base["innerMessageEncoding"] = value;
}
} [ConfigurationProperty("key", DefaultValue = "")]
public string Key
{
get
{
return base["key"] as string;
}
set
{
base["key"] = value;
}
} [ConfigurationProperty("iv", DefaultValue = "")]
public string IV
{
get
{
return base["iv"] as string;
}
set
{
base["iv"] = value;
}
} public override Type BindingElementType
{
get { return typeof(CryptEncodingBindingElementConfiguration); }
} protected override System.ServiceModel.Channels.BindingElement CreateBindingElement()
{
if (InnerMessageEncoding.ToLower() == "text")
{
CryptEncodingBindingElement bindElement = new CryptEncodingBindingElement(new System.ServiceModel.Channels.TextMessageEncodingBindingElement(), Key, IV);
return bindElement;
}
else if (InnerMessageEncoding.ToLower() == "binary")
{
CryptEncodingBindingElement bindElement = new CryptEncodingBindingElement(new System.ServiceModel.Channels.BinaryMessageEncodingBindingElement(), Key, IV);
return bindElement;
}
else if (InnerMessageEncoding.ToLower() == "mtom")
{
CryptEncodingBindingElement bindElement = new CryptEncodingBindingElement(new System.ServiceModel.Channels.MtomMessageEncodingBindingElement(), Key, IV);
return bindElement;
}
throw new Exception("只支持Text,Binary,MTOM三种内置编码器!");
}
}
}
重载实现之后,我们就可以使用它在App.Config或者Web.Config来配置BindingElement,使用的方法为:
1. 在<system.serviceModel><extensions> <bindingElementExtensions>中添加新的配置节点的绑定。
2. 创建新的注册后的节点到自定义绑定中。
来看一下服务的配置文件吧:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<clear/>
<service name="Robin_Wcf_CustomMessageEncoder_SvcLib.Service1">
<host>
<baseAddresses>
<add baseAddress="http://127.0.0.1:8081/"/>
</baseAddresses>
</host>
<endpoint address="Robin_Wcf_Formatter" name="ep" contract="Robin_Wcf_CustomMessageEncoder_SvcLib.IService1" binding="customBinding" bindingConfiguration="myBinding"></endpoint>
</service>
</services>
<bindings>
<customBinding>
<binding name="myBinding">
<cryptMessageEncoding key="JggkieIw7JM=" iv="XdTkT85fZ0U=" innerMessageEncoding="Binary"/>
<httpTransport/>
</binding>
</customBinding>
</bindings>
<extensions>
<bindingElementExtensions>
<add name="cryptMessageEncoding" type="RobinLib.CryptEncodingBindingElementConfiguration,RobinLib,Version=1.0.0.0, Culture=neutral,PublicKeyToken=null"/>
</bindingElementExtensions>
</extensions>
</system.serviceModel>
</configuration>
托管服务的代码就轻便了好多,如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using Robin_Wcf_CustomMessageEncoder_SvcLib;
using System.ServiceModel.Channels;
using RobinLib; namespace Robin_Wcf_CustomMessageEncoder_Host
{
class Program
{
static void Main(string[] args)
{
ServiceHost host = new ServiceHost(typeof(Service1));
if (host.Description.Behaviors.Find<System.ServiceModel.Description.ServiceMetadataBehavior>() == null)
{
System.ServiceModel.Description.ServiceMetadataBehavior svcMetaBehavior = new System.ServiceModel.Description.ServiceMetadataBehavior();
svcMetaBehavior.HttpGetEnabled = true;
svcMetaBehavior.HttpGetUrl = new Uri("http://127.0.0.1:8001/Mex");
host.Description.Behaviors.Add(svcMetaBehavior);
}
host.Opened += new EventHandler(delegate(object obj, EventArgs e)
{
Console.WriteLine("服务已经启动!");
});
host.Open();
Console.Read();
}
}
}
WCF进阶:扩展bindingElementExtensions支持对称加密传输的更多相关文章
- ssl原理,非对称加密握手,对称加密传输
SSL的基本思想是用非对称加密来建立链接(握手阶段),用对称加密来传输数据(传输阶段).这样既保证了密钥分发的安全,也保证了通信的效率. SSL握手,单方服务器认证(一般的浏览器上网) SSL握手,双 ...
- Vsftpd支持SSL加密传输
ftp传输数据是明文,弄个抓包软件就可以通过数据包来分析到账号和密码,为了搭建一个安全性比较高ftp,可以结合SSL来解决问题 SSL(Secure Socket Layer)工作于传输层和应用程 ...
- 工作中拓展的加密解密传输方式. DES对称加密传输.
系统间通过xml传输, 不能采用明文, 就加密传输. 秘钥(真正有效的是前8位)存储于配置中. public static string EncryptStr(this string content, ...
- 搭建支持SSL加密传输的vftpd
让vsftpd支持SSL 必须让OPENSSL≥0.9.6版本还有就是本身vsftpd版本是否支持 查询vsftpd软件是否支持SSL [root@localhost vsftpd]# ...
- [Node.js] 对称加密、公钥加密和RSA
原文地址:http://www.moye.me/2015/06/14/cryptography_rsa/ 引子 对于加解密,我一直处于一种知其然不知其所以然的状态,项目核心部分并不倚重加解密算法时,可 ...
- HTTPS加密传输过程
HTTPS加密传输过程 HTTPS全称Hyper Text Transfer Protocol over SecureSocket Layer,是以安全为目标的HTTP通道,在HTTP的基础上通过传输 ...
- linux下使用vsftp搭建FTP服务器:匿名登录,账号登录,SSL加密传输
目录 一.关于FTP和VSFTP 二.ftp.sftp.vsftp.vsftpd的区别 三.项目一:搭建一台所有人都可以访问的通用FTP服务器 3.1 项目要求 3.2 项目思路分析 3.3 使用vs ...
- PHP的OpenSSL加密扩展学习(一):对称加密
我们已经学过不少 PHP 中加密扩展相关的内容了.而今天开始,我们要学习的则是重点中的重点,那就是 OpenSSL 加密扩展的使用.为什么说它是重点中的重点呢?一是 OpenSSL 是目前 PHP 甚 ...
- SQL Server 2008, 2008 R2, 2012 and 2014 完全支持TLS1.2加密传输
SQL Server 2008, 2008 R2, 2012 and 2014 完全支持TLS1.2加密传输 微软高兴地宣布所有主流SQL Server客户端驱动和SQL Server发行版已经支持T ...
随机推荐
- 2018ICPC焦作 D-Keiichi Tsuchiya the Drift King /// 几何
题目大意: https://nanti.jisuanke.com/t/34142 有一个弯道抽象成圆的一部分 车子抽象成矩形 漂移过程中矩形上边会与圆的圆心在同一条直线上 以右上点贴着弯道边缘进行漂移 ...
- Jmeter-----请求依赖之JsonExtractor
层级关系填写: 1.第一个必须是$ 2.用英文状态下的 . 来代表下一个层级
- iOS_iPhone App自动化测试
无线客户端的发展很快,特别针对是android和ios两款无线操作系统的客户端应用,相应的测试工具也应运而生,这里主要给大家介绍一些针对 iPhone App的自动化测试工具. 首先 ...
- COGS2353 【HZOI2015】有标号的DAG计数 I
题面 题目描述 给定一正整数n,对n个点有标号的有向无环图(可以不连通)进行计数,输出答案mod 10007的结果 输入格式 一个正整数n 输出格式 一个数,表示答案 样例输入 3 样例输出 25 提 ...
- 如何设置树莓派 VNC 的分辨率
当我们使用 VNC 连接到树莓派时,默认的分辨率非常低.甚至无法显示整个桌面,因此我们需要对分辨率进行设置.在树莓派上设置 VNC 的分辨率很简单,在终端运行下面指令进入设置界面设置. 1 sudo ...
- Java 虚拟机 - ClassLoader
ClassLoader定义 ClassLoader种类 BootStrapClassLoader无法在IDEA里面查看源代码,只能看JVM 源码才能找到. ExtClassLoader,会从Syste ...
- jmeter+ant+jenkins 搭建接口自动化测试环境
过程参考:http://www.cnblogs.com/lxs1314/p/7487066.html 1. 安装ant 2. 安装jenkins 遇到问题: 启动Tomcat后,访问http://lo ...
- js代码触发事件
/*** * 需要触发谁的点击事件 * @param how_id 节点的id 如:<input id='test'/> 则how_id=test * @param how_this 这个 ...
- Vue+Iview+Node 安装环境 运行测试Vue
1.运行环境及设置 备注:建议设置 npm config set registry https://registry.npm.taobao.org 2.全局安装vue/cli 3.创建vue 项目 v ...
- Duilib中各个类的简单介绍
DirectUI意为直接在父窗口上绘图(Paint on parent dc directly).即子窗口不以窗口句柄的形式创建(windowless),只是逻辑上的窗口,绘制在父窗口之上.微软的“D ...