前面两篇文章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支持对称加密传输的更多相关文章

  1. ssl原理,非对称加密握手,对称加密传输

    SSL的基本思想是用非对称加密来建立链接(握手阶段),用对称加密来传输数据(传输阶段).这样既保证了密钥分发的安全,也保证了通信的效率. SSL握手,单方服务器认证(一般的浏览器上网) SSL握手,双 ...

  2. Vsftpd支持SSL加密传输

    ftp传输数据是明文,弄个抓包软件就可以通过数据包来分析到账号和密码,为了搭建一个安全性比较高ftp,可以结合SSL来解决问题   SSL(Secure Socket Layer)工作于传输层和应用程 ...

  3. 工作中拓展的加密解密传输方式. DES对称加密传输.

    系统间通过xml传输, 不能采用明文, 就加密传输. 秘钥(真正有效的是前8位)存储于配置中. public static string EncryptStr(this string content, ...

  4. 搭建支持SSL加密传输的vftpd

    让vsftpd支持SSL 必须让OPENSSL≥0.9.6版本还有就是本身vsftpd版本是否支持 查询vsftpd软件是否支持SSL        [root@localhost vsftpd]# ...

  5. [Node.js] 对称加密、公钥加密和RSA

    原文地址:http://www.moye.me/2015/06/14/cryptography_rsa/ 引子 对于加解密,我一直处于一种知其然不知其所以然的状态,项目核心部分并不倚重加解密算法时,可 ...

  6. HTTPS加密传输过程

    HTTPS加密传输过程 HTTPS全称Hyper Text Transfer Protocol over SecureSocket Layer,是以安全为目标的HTTP通道,在HTTP的基础上通过传输 ...

  7. linux下使用vsftp搭建FTP服务器:匿名登录,账号登录,SSL加密传输

    目录 一.关于FTP和VSFTP 二.ftp.sftp.vsftp.vsftpd的区别 三.项目一:搭建一台所有人都可以访问的通用FTP服务器 3.1 项目要求 3.2 项目思路分析 3.3 使用vs ...

  8. PHP的OpenSSL加密扩展学习(一):对称加密

    我们已经学过不少 PHP 中加密扩展相关的内容了.而今天开始,我们要学习的则是重点中的重点,那就是 OpenSSL 加密扩展的使用.为什么说它是重点中的重点呢?一是 OpenSSL 是目前 PHP 甚 ...

  9. 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 ...

随机推荐

  1. 使用Pyppeteer进行gmail模拟登录

    import asyncio import time from pyppeteer import launch async def gmailLogin(username, password, url ...

  2. jquery与zend framework编写的联动选项效果

    html部分: <pre name="code" class="html"><!DOCTYPE html PUBLIC "-//W3 ...

  3. vue echart例——柱状图及高度自适应

    1.安装 npm install echarts -s 2.例——点击tab切换时柱状图重绘,高度根据返回数据设置. <template> <div> <ul id=&q ...

  4. fping简介及使用方法

    fping命令的官网为:http://fping.org/ 历史版本下载地址:http://fping.org/dist/ 第一步:安装. wget http://fping.org/dist/fpi ...

  5. PL SQL 12.0.7的安装及注册码,汉化包,连接Oracle远程数据库,中文乱码问题处理

    首先,在官网下载PL SQL 的对应版本,本机是64位的就下载64位的,网址:https://www.allroundautomations.com/downloads.html#PLS 点击应用程序 ...

  6. INSTALL_FAILED_TEST_ONLY oppor11p 安装时出现的问题

      刚开始出现这个问题 我很懵逼, 因为我之前一直运行都好好的  !!我在网上查了好多资料 试了好几种办法 我先说下我成功的办法       方法1: Android Studio 3.0会在debu ...

  7. 能轻松背板子的FWT(快速沃尔什变换)

    FWT应用 我不知道\(FWT\)的严格定义 百度百科和维基都不知道给一坨什么****东西** FWT(Fast Walsh Fransform),中文名快速沃尔什变换 然后我也不知道\(FWT\)到 ...

  8. vuex的简单介绍

    .vuex的定义 )Vuex 是一个专门为 Vue.js 应用程序开发的状态管理模式,使用插件的形式引进项目中 )集中存储和管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化 ...

  9. hexo 错误汇总

    文章目录 发布文章遇到: 发布文章的时候出现错误: 代码推送到github,hexo g -d 半天推送不上去 记录一次hexo+coding hexo s本都没问题,hexo g -d 样式并未改变 ...

  10. ubuntu 没有桌面 没有图标,只剩下壁纸

    sudo apt-get update sudo apt-get install --reinstall ubuntu-desktop sudo apt-get install unity sudo ...