有次我们有个项目需要Call 一个 Java 的 web service, Soap包中需要一个 Security Head

  1. <soapenv:Header>
  2. <wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
  3. <wsse:UsernameToken xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" wsu:Id="UsernameToken-1" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
  4. <wsse:Username>username</wsse:Username>
  5. <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">password</wsse:Password>
  6. </wsse:UsernameToken>
  7. </wsse:Security>
  8. </soapenv:Header>

但是.net 默认的 Credentials 添加的 UserName 不符合这种格式

  1. orgClient.ClientCredentials.UserName.UserName = "userName";
  2. orgClient.ClientCredentials.UserName.Password = "password";

所以总是报错

System.Web.Services.Protocols.SoapHeaderException: An error was

discovered processing the <wsse: Security> header

没奈何,就只有用力气活,手动的把这段WSSE 的 head 添加到 Soap 包里面去了。

  1. orgClient.Endpoint.EndpointBehaviors.Add(new CustomEndpointBehavior());

下面是Behavior

  1. /// <summary>
  2.     /// Represents a run-time behavior extension for a client endpoint.
  3.     /// </summary>
  4.     public class CustomEndpointBehavior : IEndpointBehavior
  5.     {
  6.         /// <summary>
  7.         /// Implements a modification or extension of the client across an endpoint.
  8.         /// </summary>
  9.         /// <param name="endpoint">The endpoint that is to be customized.</param>
  10.         /// <param name="clientRuntime">The client runtime to be customized.</param>
  11.         public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
  12.         {
  13.             clientRuntime.ClientMessageInspectors.Add(new ClientMessageInspector());
  14.         }
  15.  
  16.         /// <summary>
  17.         /// Implement to pass data at runtime to bindings to support custom behavior.
  18.         /// </summary>
  19.         /// <param name="endpoint">The endpoint to modify.</param>
  20.         /// <param name="bindingParameters">The objects that binding elements require to support the behavior.</param>
  21.         public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
  22.         {
  23.             // Nothing special here
  24.         }
  25.  
  26.         /// <summary>
  27.         /// Implements a modification or extension of the service across an endpoint.
  28.         /// </summary>
  29.         /// <param name="endpoint">The endpoint that exposes the contract.</param>
  30.         /// <param name="endpointDispatcher">The endpoint dispatcher to be modified or extended.</param>
  31.         public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
  32.         {
  33.             // Nothing special here
  34.         }
  35.  
  36.         /// <summary>
  37.         /// Implement to confirm that the endpoint meets some intended criteria.
  38.         /// </summary>
  39.         /// <param name="endpoint">The endpoint to validate.</param>
  40.         public void Validate(ServiceEndpoint endpoint)
  41.         {
  42.             // Nothing special here
  43.         }
  44.     }

请注意13行红色部分的代码,相当于一层层的使用了Provider 的模式

  1. /// <summary>
  2.     /// Represents a message inspector object that can be added to the <c>MessageInspectors</c> collection to view or modify messages.
  3.     /// </summary>
  4.     public class ClientMessageInspector : IClientMessageInspector
  5.     {
  6.         /// <summary>
  7.         /// Enables inspection or modification of a message before a request message is sent to a service.
  8.         /// </summary>
  9.         /// <param name="request">The message to be sent to the service.</param>
  10.         /// <param name="channel">The WCF client object channel.</param>
  11.         /// <returns>
  12.         /// The object that is returned as the <paramref name="correlationState " /> argument of
  13.         /// the <see cref="M:System.ServiceModel.Dispatcher.IClientMessageInspector.AfterReceiveReply(System.ServiceModel.Channels.Message@,System.Object)" /> method.
  14.         /// This is null if no correlation state is used.The best practice is to make this a <see cref="T:System.Guid" /> to ensure that no two
  15.         /// <paramref name="correlationState" /> objects are the same.
  16.         /// </returns>
  17.         public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, IClientChannel channel)
  18.         {
  19.             SoapSecurityHeader header = new SoapSecurityHeader("UsernameToken-1", UserName, Password, "");
  20.  
  21.             request.Headers.Add(header);
  22.  
  23.             return header.Id;
  24.         }
  25.  
  26.         /// <summary>
  27.         /// Enables inspection or modification of a message after a reply message is received but prior to passing it back to the client application.
  28.         /// </summary>
  29.         /// <param name="reply">The message to be transformed into types and handed back to the client application.</param>
  30.         /// <param name="correlationState">Correlation state data.</param>
  31.         public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
  32.         {
  33.             var a = reply;
  34.             // Nothing special here
  35.         }
  36.     }

下面是写入Head的部分

  1. public class SoapSecurityHeader : MessageHeader
  2.     {
  3.         private readonly string _password, _username, _nonce;
  4.         private readonly DateTime _createdDate;
  5.  
  6.         public SoapSecurityHeader(string id, string username, string password, string nonce)
  7.         {
  8.             _password = password;
  9.             _username = username;
  10.             _nonce = nonce;
  11.             _createdDate = DateTime.Now;
  12.             this.Id = id;
  13.         }
  14.  
  15.         public string Id { get; set; }
  16.  
  17.         public override string Name
  18.         {
  19.             get { return "Security"; }
  20.         }
  21.  
  22.         public override string Namespace
  23.         {
  24.             get { return "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"; }
  25.         }
  26.  
  27.         protected override void OnWriteStartHeader(XmlDictionaryWriter writer, MessageVersion messageVersion)
  28.         {
  29.             writer.WriteStartElement("wsse", Name, Namespace);
  30.             writer.WriteXmlnsAttribute("wsse", Namespace);
  31.         }
  32.  
  33.         protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
  34.         {
  35.             writer.WriteStartElement("wsse", "UsernameToken", Namespace);
  36.             writer.WriteAttributeString("Id", "UsernameToken-10");
  37.             writer.WriteAttributeString("wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
  38.  
  39.             writer.WriteStartElement("wsse", "Username", Namespace);
  40.             writer.WriteValue(_username);
  41.             writer.WriteEndElement();
  42.  
  43.             writer.WriteStartElement("wsse", "Password", Namespace);
  44.             writer.WriteAttributeString("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");
  45.             writer.WriteValue(_password);
  46.             writer.WriteEndElement();
  47.  
  48.             writer.WriteStartElement("wsse", "Nonce", Namespace);
  49.             writer.WriteAttributeString("EncodingType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary");
  50.             writer.WriteValue(_nonce);
  51.             writer.WriteEndElement();
  52.  
  53.             writer.WriteStartElement("wsse", "Created", Namespace);
  54.             writer.WriteValue(_createdDate.ToString("YYYY-MM-DDThh:mm:ss"));
  55.             writer.WriteEndElement();
  56.  
  57.             writer.WriteEndElement();
  58.         }
  59.     }

至此大功告成!

扩展Wcf call security service, 手动添加 Soap Security Head.的更多相关文章

  1. WCF 在VS中,添加服务引用,地址输入http://ip/Service.svc,点击前往,提示错误,内容如下:

    WCF的service端的webconfig如下: <?xml version="1.0"?> <configuration> <system.ser ...

  2. centos6.5 gsoap安装过程+ php添加soap扩展

    参考博客: CentOS编译安装gSOAP Linux C实现webservice调用 安装gsoap流程  里面提到make时可能碰到的问题 还没有用到 1.从官网下载最新的版本:http://so ...

  3. wcf和web service的区别

    1.WebService:严格来说是行业标准,不是技术,使用XML扩展标记语言来表示数据(这个是夸语言和平台的关键).微软的Web服务实现称为ASP.NET Web Service.它使用Soap简单 ...

  4. WCF和Web Service的 区(guan)别(xi)

    参考文献:http://social.microsoft.com/Forums/zh-CN/c06420d1-69ba-4aa6-abe5-242e3213b68f/wcf-webservice 之前 ...

  5. WCF与 Web Service的区别是什么?各自的优点在哪里呢?

    这是很多.NET开发人员容易搞错的问题.面试的时候也经常遇到,初学者也很难分快速弄明白 Web service: .net技术中其实就指ASP.NET Web Service,用的时间比较长,微软其实 ...

  6. 如何手动添加Windows服务和如何把一个服务删除

    windows 手动添加服务方法一:修改注册表 在注册表编辑器,展开分支"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services" ...

  7. Windows服务的手动添加和删除方法

    Windows服务的手动添加和删除方法 服务,是指执行指定系统功能的程序.例程或进程,以便支持其他程序,尤其是低层(接近硬件)程序.其实,服务就是一种特殊的应用程序,它从服务启动开始就一直处于运行状态 ...

  8. 解决 Cocos2d-x 中 Android.mk 手动添加源文件

    转自:http://blog.csdn.net/ypfsoul/article/details/8909178 Makefile Android.mk 引发的思索 在我们编写 Android 平台 c ...

  9. Quartz动态添加定时任务执行sql(服务启动添加+手动添加)

    系统用来每天插入视图数据... 一.数据库表设计 1.接口配置表(t_m_db_interface_config) 2.接口日志表(t_m_db_interface_log) 3.前端配置页面 查询页 ...

随机推荐

  1. 如何获取hibernate代理类代理的实际对象实例?

    在hibernate中,通过sql语句查询带clob字段的记录,查出来的结果集是List<HashMap<String,Object>>类型,在调用jackson的接口转为js ...

  2. 在ubuntu 12.04 x64下编译hadoop2.4

    自己编译hadoop:x64 1.安装依赖包 sudo apt-get install g++ autoconf automake libtool cmake zlib1g-dev pkg-confi ...

  3. quick-3.5 eclipse android

    quick-3.5 eclipse android  上遇到的 问题 首先是已经安装了SDK NDK ADT 环境变量都已经配置好了 直接打开项目然后运行 却出现这个鸟问题如图: NDK_ROOT = ...

  4. 开源战棋 SLG 游戏框架设计思考(二)规则系统要考虑的因素

    游戏对象 1. 地块方格 地形:山脉.丘陵.乔木林.灌木林.平原.河流.湖泊.海洋.雪原.沼泽.沙漠.暗礁.滩涂.岛屿等等(需完善) 设施:铁路.公路.桥梁.机场.城市.村庄.岸防炮.要塞.废墟等等( ...

  5. 微软的HLSL Shader Model 6.0 compiler要转向LLVM了,开源的节奏. Apple/Khronos都有各自计划

    So, Microsoft is making an opensource HLSL-to-almost-LLVM compiler, and Khronos is making an opensou ...

  6. Xamarin Android 绑定jar库同时将so库打包进去

    1.在创建的Bindings Library项目中,新建Assets目录: 2.Assets目录下再分别创建armeabi,armeabi-v7a,x86三个目录: 3.将so文件分布copy到三个目 ...

  7. Android Unable to instantiate activity: Didn't find class on path

    Android Unable to instantiate activity: Didn't find class on path After i spend a while on this prob ...

  8. php5.6 一键编译

    1. 替换成aliyun的源 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup wget -O ...

  9. Angular-ngtable联动全选

    之前于Angular第三方插件ngTable的官网demo上看到的例子,但苦于demo中联动全选为选中所有,项目中并不适用,因此做了下小小的修改,修改目的只是为实现其功能,方法不敢苟同,若有更加简便的 ...

  10. Unity WebGL MoonSharp崩溃问题

    当前Unity的代码更新方案基本都选择的ULua,而我们项目还需要考虑Web平台,ULua不支持WebGL,所以决定选择MoonSharp.MoonSharp(http://www.moonsharp ...