扩展Wcf call security service, 手动添加 Soap Security Head.
有次我们有个项目需要Call 一个 Java 的 web service, Soap包中需要一个 Security Head
- <soapenv:Header>
- <wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
- <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">
- <wsse:Username>username</wsse:Username>
- <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">password</wsse:Password>
- </wsse:UsernameToken>
- </wsse:Security>
- </soapenv:Header>
但是.net 默认的 Credentials 添加的 UserName 不符合这种格式
- orgClient.ClientCredentials.UserName.UserName = "userName";
- orgClient.ClientCredentials.UserName.Password = "password";
所以总是报错
System.Web.Services.Protocols.SoapHeaderException: An error was
discovered processing the <wsse: Security> header
没奈何,就只有用力气活,手动的把这段WSSE 的 head 添加到 Soap 包里面去了。
- orgClient.Endpoint.EndpointBehaviors.Add(new CustomEndpointBehavior());
下面是Behavior
- /// <summary>
- /// Represents a run-time behavior extension for a client endpoint.
- /// </summary>
- public class CustomEndpointBehavior : IEndpointBehavior
- {
- /// <summary>
- /// Implements a modification or extension of the client across an endpoint.
- /// </summary>
- /// <param name="endpoint">The endpoint that is to be customized.</param>
- /// <param name="clientRuntime">The client runtime to be customized.</param>
- public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
- {
- clientRuntime.ClientMessageInspectors.Add(new ClientMessageInspector());
- }
- /// <summary>
- /// Implement to pass data at runtime to bindings to support custom behavior.
- /// </summary>
- /// <param name="endpoint">The endpoint to modify.</param>
- /// <param name="bindingParameters">The objects that binding elements require to support the behavior.</param>
- public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
- {
- // Nothing special here
- }
- /// <summary>
- /// Implements a modification or extension of the service across an endpoint.
- /// </summary>
- /// <param name="endpoint">The endpoint that exposes the contract.</param>
- /// <param name="endpointDispatcher">The endpoint dispatcher to be modified or extended.</param>
- public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
- {
- // Nothing special here
- }
- /// <summary>
- /// Implement to confirm that the endpoint meets some intended criteria.
- /// </summary>
- /// <param name="endpoint">The endpoint to validate.</param>
- public void Validate(ServiceEndpoint endpoint)
- {
- // Nothing special here
- }
- }
请注意13行红色部分的代码,相当于一层层的使用了Provider 的模式
- /// <summary>
- /// Represents a message inspector object that can be added to the <c>MessageInspectors</c> collection to view or modify messages.
- /// </summary>
- public class ClientMessageInspector : IClientMessageInspector
- {
- /// <summary>
- /// Enables inspection or modification of a message before a request message is sent to a service.
- /// </summary>
- /// <param name="request">The message to be sent to the service.</param>
- /// <param name="channel">The WCF client object channel.</param>
- /// <returns>
- /// The object that is returned as the <paramref name="correlationState " /> argument of
- /// the <see cref="M:System.ServiceModel.Dispatcher.IClientMessageInspector.AfterReceiveReply(System.ServiceModel.Channels.Message@,System.Object)" /> method.
- /// 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
- /// <paramref name="correlationState" /> objects are the same.
- /// </returns>
- public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, IClientChannel channel)
- {
- SoapSecurityHeader header = new SoapSecurityHeader("UsernameToken-1", UserName, Password, "");
- request.Headers.Add(header);
- return header.Id;
- }
- /// <summary>
- /// Enables inspection or modification of a message after a reply message is received but prior to passing it back to the client application.
- /// </summary>
- /// <param name="reply">The message to be transformed into types and handed back to the client application.</param>
- /// <param name="correlationState">Correlation state data.</param>
- public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
- {
- var a = reply;
- // Nothing special here
- }
- }
下面是写入Head的部分
- public class SoapSecurityHeader : MessageHeader
- {
- private readonly string _password, _username, _nonce;
- private readonly DateTime _createdDate;
- public SoapSecurityHeader(string id, string username, string password, string nonce)
- {
- _password = password;
- _username = username;
- _nonce = nonce;
- _createdDate = DateTime.Now;
- this.Id = id;
- }
- public string Id { get; set; }
- public override string Name
- {
- get { return "Security"; }
- }
- public override string Namespace
- {
- get { return "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"; }
- }
- protected override void OnWriteStartHeader(XmlDictionaryWriter writer, MessageVersion messageVersion)
- {
- writer.WriteStartElement("wsse", Name, Namespace);
- writer.WriteXmlnsAttribute("wsse", Namespace);
- }
- protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
- {
- writer.WriteStartElement("wsse", "UsernameToken", Namespace);
- writer.WriteAttributeString("Id", "UsernameToken-10");
- writer.WriteAttributeString("wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
- writer.WriteStartElement("wsse", "Username", Namespace);
- writer.WriteValue(_username);
- writer.WriteEndElement();
- writer.WriteStartElement("wsse", "Password", Namespace);
- writer.WriteAttributeString("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");
- writer.WriteValue(_password);
- writer.WriteEndElement();
- writer.WriteStartElement("wsse", "Nonce", Namespace);
- writer.WriteAttributeString("EncodingType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary");
- writer.WriteValue(_nonce);
- writer.WriteEndElement();
- writer.WriteStartElement("wsse", "Created", Namespace);
- writer.WriteValue(_createdDate.ToString("YYYY-MM-DDThh:mm:ss"));
- writer.WriteEndElement();
- writer.WriteEndElement();
- }
- }
至此大功告成!
扩展Wcf call security service, 手动添加 Soap Security Head.的更多相关文章
- WCF 在VS中,添加服务引用,地址输入http://ip/Service.svc,点击前往,提示错误,内容如下:
WCF的service端的webconfig如下: <?xml version="1.0"?> <configuration> <system.ser ...
- centos6.5 gsoap安装过程+ php添加soap扩展
参考博客: CentOS编译安装gSOAP Linux C实现webservice调用 安装gsoap流程 里面提到make时可能碰到的问题 还没有用到 1.从官网下载最新的版本:http://so ...
- wcf和web service的区别
1.WebService:严格来说是行业标准,不是技术,使用XML扩展标记语言来表示数据(这个是夸语言和平台的关键).微软的Web服务实现称为ASP.NET Web Service.它使用Soap简单 ...
- WCF和Web Service的 区(guan)别(xi)
参考文献:http://social.microsoft.com/Forums/zh-CN/c06420d1-69ba-4aa6-abe5-242e3213b68f/wcf-webservice 之前 ...
- WCF与 Web Service的区别是什么?各自的优点在哪里呢?
这是很多.NET开发人员容易搞错的问题.面试的时候也经常遇到,初学者也很难分快速弄明白 Web service: .net技术中其实就指ASP.NET Web Service,用的时间比较长,微软其实 ...
- 如何手动添加Windows服务和如何把一个服务删除
windows 手动添加服务方法一:修改注册表 在注册表编辑器,展开分支"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services" ...
- Windows服务的手动添加和删除方法
Windows服务的手动添加和删除方法 服务,是指执行指定系统功能的程序.例程或进程,以便支持其他程序,尤其是低层(接近硬件)程序.其实,服务就是一种特殊的应用程序,它从服务启动开始就一直处于运行状态 ...
- 解决 Cocos2d-x 中 Android.mk 手动添加源文件
转自:http://blog.csdn.net/ypfsoul/article/details/8909178 Makefile Android.mk 引发的思索 在我们编写 Android 平台 c ...
- Quartz动态添加定时任务执行sql(服务启动添加+手动添加)
系统用来每天插入视图数据... 一.数据库表设计 1.接口配置表(t_m_db_interface_config) 2.接口日志表(t_m_db_interface_log) 3.前端配置页面 查询页 ...
随机推荐
- 在docker 中配置hadoop1.2.1 cluser
最近一直在找工作,比较空闲,就没事研究一下hadoop,网上的视频及书,讲的差不多都是1.2.1这个版本,然后就试着在docker中搭建了一个hadoop集群, 项目已经放到了github上面了,供新 ...
- HDU1242 BFS+优先队列
Rescue Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Subm ...
- ZK textbox Constraint验证
test.zul: <?page title="" contentType="text/html;charset=UTF-8"?> <zk x ...
- JavaScript之闭包就是个子公司
在计算机科学中,闭包(Closure)是词法闭包(Lexical Closure)的简称,是引用了自由变量的函数.这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外.所以,有 ...
- 2016.9.20 java上课作业
此程序从命令行接收多个数字,求和之后输出
- HDU 1166 敌兵布阵(分块)
敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submi ...
- 不小心删除了sysWOW64下的webio.dll
weibo的桌面客户端留了一个服务,在syswow64目录下留了个exe文件,看着旁边好像还有个weibo.dll,就把试着也删除了,但是删除不掉,我就进安全模式删除了(f8在Windows的启动界面 ...
- 获取程序的SHA1值
android获取程序的SHA1值 public static String getSHA1(Context context) { try { PackageInfo info = context.g ...
- MYSQL提权总结
最近在测试一个项目,遇到了MYSQL数据库,想尽办法提权,最终都没有成功,很是郁闷,可能是自己很久没有研究过提权导致的吧,总结一下MYSQL提权的各种姿势吧,权当复习了.关于mysql提权的方法也就那 ...
- MySQL 插入数据 通过命令提示窗口插入数据
MySQL 表中使用 INSERT INTO SQL语句来插入数据. 你可以通过 mysql> 命令提示窗口中向数据表中插入数据,或者通过PHP脚本来插入数据. 语法 以下为向MySQL数据表插 ...