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 ...
随机推荐
- 推荐5本纯Java技术书,你看过几本?
51小长假了,大家应该对它又爱又痛,爱的是终于可以到处浪了,痛的是没钱只能穷游,而且还到处都是人,结果变成了堵高速.去看人头.去蒸饺子,真是受罪啊.. 所以,对于小长假的痛,我相信还是有一部分人会选择 ...
- sql 特殊时间值 第一天或最后一天 无计算错误
DECLARE @dt datetimeSET @dt=GETDATE() DECLARE @number intSET @number=3 --1.指定日期该年的第一天或最后一天--A. 年的第一天 ...
- ASP.NET MVC easyUI-datagrid 分页
本文写的是最简单的 按照API文档来写的分页.就是插件自带的分页效果. 一.html代码:field就是代表你后台数据的对应的列名. <table id="dg" class ...
- arc098E Range Minimum Queries
题意:给你一个n个数的数组,每次能够选取连续的长度为K的子序列,取出其中任意一个最小元素. 一共操作Q次.问取出的元素中Max-Min最小是多少? 标程: #include<bits/stdc+ ...
- php相关操作
array_unshift : 数组头部追加 用法如下: $arr = ['demo','dmoa']; array_unshift($arr,'demob'); //在$arr的前面追加demob ...
- MySQL语句基本操作增删改查
select * from 表名; --------->效率低
- 【转载】Abstract Factory Step by Step --- 抽象工厂
抽象工厂是创建型模式的代表,其他的还有单件(Singleton).生成器(Builder).工厂方法(Factory Method)以及原型(Prototype),模式本身没有好坏之分,只有适用不适用 ...
- 牛客多校第四场 A meeting 树的半径
题意: 有一棵树,树上有许多人,他们要聚会,找一个点使得所有人到这个点的距离的最大值最小. 题解: 首先,以一个有人的点为根,求一个生成树,删掉所有没有人的子树,保证所有的悬挂点(只连接一条边的点)都 ...
- memcpy函数实现中的优化
今天浏览Google面试题的时候,有看到一个memcpy的实现,以及如何去优化memcpy. 我对memcpy的实现的记忆就是,拷贝的时候需要从后往前拷贝,为何防止内存重叠. 但是如果去优化它我没有想 ...
- 命令学习_nslookup
nslookup 域名 这是最常用最简单的用法,可以直接获得目标域名的IP地址和CNAME. 如下是A记录的返回情况 nslookup命令会采用先反向解释获得使用的DNS服务器的名称,上图中ns.gu ...