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 ...
随机推荐
- 常用sign算法
所有参数包括appkey或者token拼接成&key=value格式 转小写 正序排序 MD5后得到sign
- Error creating bean with name 'unMblTotController': 注入失败
今天新来的小伙子,进公司做项目,然后自己新建了包,出了以下错误 y.UnsatisfiedDependencyException: Error creating bean with name 'unM ...
- OC开发系列-类与对象
面向对象 面向对象思想是一种解决问题的思想, 不在是面向过程的去思考问题怎样解决.面向对象解决问题时首先要考虑需要找几个对象能解决这个问题. 常见的概念: * Object Oriented 面向对象 ...
- iOS开发系列-HTTPS
HTTPS 网景在1994年创建了HTTPS,并应用在网景导航者浏览器中. 最初,HTTPS是与SSL一起使用的:在SSL逐渐演变到TLS. HTTPS协议与HTTP协议的一些不同: http是超文本 ...
- Android开发 View_自定义圆环进度条View
前言 一个实现,空心圆环的自定义View,已经封装完好,可以直接使用. 效果图 代码 import android.content.Context; import android.graphics.C ...
- COGS2356 【HZOI2015】有标号的DAG计数 IV
题面 题目描述 给定一正整数n,对n个点有标号的有向无环图进行计数. 这里加一个限制:此图必须是弱连通图. 输出答案mod 998244353的结果 输入格式 一个正整数n. 输出格式 一个数,表示答 ...
- redis笔记_源码_简单动态字符串SDS
参照:https://zcheng.ren/sourcecodeanalysis/theannotatedredissourcesds/#sds%E5%B0%8F%E7%BB%93 这里用char b ...
- Java 多线程 - synchronized与Lock的区别
https://blog.csdn.net/qq_39521554/article/details/81130442 http://www.cnblogs.com/huangbw/p/8516024. ...
- 使用ajax怎么请求跨域资源
1.ajax中添加“xhrFields”和“crossDomain”,如: $.ajax({ url: url, data: data, type: "post", xhrFiel ...
- shiro框架的组成和内部结构(下一篇为spring整合shiro)
1.shiro简介 Apache Shiro是Java的一个安全框架.功能强大,使用简单的Java安全框架,它为开发人员提供一个直观而全面的认证,授权,加密及会话管理的解决方案. 实际上,Shir ...