.Net调用Java端带有WS-Security支持的Web Service各方案实战【转】
原文:http://www.xuebuyuan.com/641669.html
到现在为止,我们AEP平台已经发布很长一段时间了,也有很多ISV接入并上线了,就语言而言,目前主要有三类:Java、.Net、Php;Java和Php的调用不存在很复杂的问题,但是.Net就要相对复杂不少, 现在已上线的ISV采用的是.Net SDK 2.0 + WSE 2.0【Web Services Enhancements】,但是随着.Net 3.0和3.5的普及,我们需要支持更多的.Net接入方案;
总的来说,针对不同的.Net SDK版本有三种实现来满足对带有WS-Security支持的Web Service调用,即WSE 2.0、WSE 3.0、WCF【Windows Communication Foundation】;其中WSE 2.0针对的是VS 2003版本,WSE 3.0针对的是VS 2005版本,WCF针对的是VS 2008,从SDK要求来看,WSE 2.0和3.0是2.0,而WCF要求是3.0或3.5;前面我的同事已经将WSE 2.0调通,但是对WSE 3.0始终无法调通,具体可以参见《Web Service 、WS-Security、Java和.net的互通(在路上-基于SCA规范的应用服务框架成长记之四》;而WCF经过微软研究院几个月的调试,也已经调通,具体可以参见《.Net在Alibaba的AEP平台上的应用》;不幸的是,针对这两种配置方案经测试是不兼容的,因为不止是.Net客户端调整配置和代码,Java服务端仍然要做出调整,这对于我们的系统侵入是非常大的,因为现在已经有ISV采用WSE 2.0实现在生产环境运行了,要想在服务端做出调整的话必须要做到无缝升级,也即线上所有的ISV客户端无需做任何修改,否则这个升级代价会非常高;
功夫不负有心人啊,经过几天的研究,终于让我找到一个更加有效的解决方案,在新的配置方案下,WSE 2.0、WSE 3.0、WCF全部都可以调试通过,并且对Java端没有任何影响,Php的调用经确认也不存在任何问题;服务端OutflowSecurity配置文件修改如下:其中,1)items中添加了Timestamp的配置,并且在Signature之前,这是为了满足WCF的测试而特意设置的,幸好这不影响其他方案的调试;
2)signatureKeyIdentifier设置为DirectReference,该配置项在前面已经提到过,他和X509KeyIdentifier一样,是将签名者的证书公共部分直接通过soap xml传递给客户端,然后客户端再和他本地的公钥证书做对比,通过之后进行签名验证;关于该配置项,在Java服务端WSS4J的javadoc中描述有误,javadoc中说该项只允许两个值:IssuerSerial和SKIKeyIdentifier,但实际上他可以取5种值,这可能是导致很多人无法在.Net环境调试通过的原因;
3)signatureParts种指定了参与签名的是Timestamp和body部分,这也是WCF所特别需要的,因为WCF要求soap xml种的header部分都要参与签名;
<items>Timestamp Signature</items>
<signatureKeyIdentifier>DirectReference</signatureKeyIdentifier>
<signatureParts>{Element}{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd}Timestamp;{Element}{}Body</signatureParts>注意,签名部分中Body的namespace是空的,而没有设置为http://schemas.xmlsoap.org/soap/envelope/(SOAP 1.1对应的ns)或者http://www.w3.org/2003/05/soap-envelope(对应SOAP 1.2),这是为了兼容SOAP 1.1和1.2两个版本,若指定了ns,则只能兼容其一,.Net、Java客户端调用默认都使用SOAP 1.1版,而WSF/PHP则默认使用1.2版本,这样就无法做到各语言的完全
服务端搞定之后,我们就可以来进行.Net客户端的调试工作了,这里就不描述证书的准备工作了,直接开始;注意:以下的配置方案是在带有WSS支持的Web Service服务端特定配置基础上调试通过的,随着服务端配置的变化,客户端的配置和编码也会有一定的调整,所以以下配置并不保证对所有服务端配置都联调成功;
WSE 2.0配置(VS 2003)
1)右键单击工程,选择WSE Settings 2.0 ...开始设置,若在VS 2005环境种使用WSE 2.0,则菜单中没有该项,需要单独打开WSE的Configuration Tool进行设置;
2)在Settings Tool中General页中选中Enable this projects for Web Services Enhancements;
3)Policy页中选中Enable Policy,点击Add ...按钮新建Policy配置文件;
4)Add or Rename Endpoint URI窗口中保留默认值<DefaultEndpoint>,点击OK;
5)保持Next,到Message Settings窗口中对Request Message、Response Message都选择Require Signatures,因为我们只需要进行签名验证,而不需要加密;
6)Next到Client Certificate窗口中,选择客户端签名需要的私钥证书;
7)Trusted Server Certificate窗口中,选择验证服务端签名需要的公钥证书;
8)保存退出,会在工程中出现policyCache.config配置文件,打开;
9)找到response对应的Policy配置项中的wsp:MessagePredicate和wssp:MessageParts,删除其中多余的配置项,只保留wsp:Body();
10)添加Web Reference,然后修改Reference.cs文件中继承的父类,由System.Web.Services.Protocols.SoapHttpClientProtocol修改为Microsoft.Web.Services2.WebServicesClientProtocol;对于此点可能在vs2003环境下面是不需要的,我只在VS 2005环境下面测试过,VS 2005下面是必须的;
11)写ws调用类并运行;
和我们以前WSE 2.0的配置相比,主要变化在于现在不需要选中Use RFC2380选项了;
WSE 3.0配置(VS 2005)
和WSE 2.0配置一样,完全借助于Configuration Tool,注意以下点:
1)可以先配置Policy再添加Web Reference引用,这样产生的代理类会自动继承Microsoft.Web.Services3.WebServicesClientProtocol;
2)调用代码中需要自己设置要使用的policy名称;
3)Security页中X.509 Certificate Settings中的选项都保持默认值,除了Store Location;
4)新建Policy时Message Protection步骤中选择要注意顺序,顺序的不同会产生很不一样的效果,结果会导致接口调用步成功,最傻瓜的操作如下图所示:
这应该是.Net下面调用带有WSS支持的Web Service最傻瓜的操作了,全向导性配置,只需要三行代码即可调用WS;
WCF配置(VS 2008)
WCF的配置又复杂一些了,因为WCF整合了许多其他的东西,而不仅仅是一个支持WS-Security的工具,配置文件中各项的选择性也非常的大,取值范围非常的广,这样反而让开发人员在配置的时候感觉到盲目;WCF也有自己的配置工具WCF Service Configuration Editor,可以从“工具”菜单栏或者开始菜单中加载;这里就不帖具体每项的配置了,因为配置工具中没有向导;直接帖一个可用的配置文件:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<!-- If you wan to turn on logging, uncomment the "sources" section below, and set the correct log files in sharedListeners section. -->
<system.diagnostics>
<sharedListeners>
<!-- TODO: Please fix the log file name here! -->
<add initializeData="F:TempTracesapp_messages_aliclient.svclog"
type="System.Diagnostics.XmlWriterTraceListener, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
name="ServiceModelMessageLoggingListener" traceOutputOptions="Timestamp">
<filter type="" />
</add>
<!-- TODO: Please fix the log file name here! -->
<add initializeData="F:TempTracesapp_tracelog_aliclient.svclog"
type="System.Diagnostics.XmlWriterTraceListener, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
name="ServiceModelTraceListener" traceOutputOptions="Timestamp">
<filter type="" />
</add>
</sharedListeners>
</system.diagnostics>
<system.serviceModel>
<!-- To turn on message logging, set these flags to "true" -->
<diagnostics>
<messageLogging logEntireMessage="false" logMalformedMessages="false"
logMessagesAtTransportLevel="false" />
</diagnostics>
<bindings>
<customBinding>
<binding name="Soap11CustomBinding">
<textMessageEncoding messageVersion="Soap11" />
<security defaultAlgorithmSuite="Basic128" allowSerializedSigningTokenOnReply="true"
authenticationMode="MutualCertificate" requireDerivedKeys="false"
securityHeaderLayout="Lax" includeTimestamp="true" keyEntropyMode="CombinedEntropy"
messageProtectionOrder="SignBeforeEncrypt" messageSecurityVersion="WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10"
requireSecurityContextCancellation="false">
<secureConversationBootstrap />
</security>
<httpTransport />
</binding>
</customBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="NewBehavior">
<clientCredentials>
<clientCertificate findValue="CN=5" storeLocation="CurrentUser"
storeName="My" x509FindType="FindBySubjectDistinguishedName" />
<serviceCertificate>
<defaultCertificate findValue="CN=alisoft" storeLocation="CurrentUser"
storeName="My" x509FindType="FindBySubjectDistinguishedName" />
<authentication customCertificateValidatorType="" certificateValidationMode="PeerOrChainTrust" />
</serviceCertificate>
<issuedToken cacheIssuedTokens="false" />
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
<client>
<!--121.0.18.160-->
<endpoint address="http://localhost:1688/webservice/AppConsumeService"
behaviorConfiguration="NewBehavior" binding="customBinding"
bindingConfiguration="Soap11CustomBinding" contract="ServiceReference1.AppConsumeServicePortType"
name="Soap11CustomBindingPort">
<identity>
<dns value="alisoft" />
<certificateReference x509FindType="FindBySubjectName" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>客户端调用代码为:
ServiceReference1.AppConsumeServicePortTypeClient c = new ServiceReference1.AppConsumeServicePortTypeClient("Soap11CustomBindingPort");
//设置保护级别为签名
c.Endpoint.Contract.ProtectionLevel = System.Net.Security.ProtectionLevel.Sign;
string bal = c.checkBalance("85", "afc376c9-d14b-4820-bc77-e22878fa8ce3", 11);
Console.WriteLine("bal is:" + bal);至于WCF配置中的细项我也还没有深入探讨过,以上的配置都是基于微软亚洲研究院联调成功的配置之上的;
.Net调用Java端带有WS-Security支持的Web Service各方案实战【转】的更多相关文章
- .Net调用Java端带有WS-Security支持的Web Service【亲测通过】
做了几年的开发,今天终于鼓起勇气开通了博客园.平时都是找各种大牛,看他们的分享博客的解决BUG.从今天起,我也开始分享我学习之路.还望大家多多支持! 最近收到一个采用Axis2实现的WebServic ...
- 【转】基于CXF Java 搭建Web Service (Restful Web Service与基于SOAP的Web Service混合方案)
转载:http://www.cnblogs.com/windwithlife/archive/2013/03/03/2942157.html 一,选择一个合适的,Web开发环境: 我选择的是Eclip ...
- android NDK 实用学习(五)-c++端调用java接口
1,阅读此文章前请阅读前面文章,以免阅读出现障碍: android NDK 实用学习(一)-获取java端类及其类变量 android NDK 实用学习(二)-java端对象成员赋值和获取对象成员值 ...
- NET调用Java之100-Continue的坑
场景:这段时间开发的时候遇到了需要NET调用java的restful api的情况,java端用的服务器是tomcat,框架是spring boot,net调用java端的接口之后只要java端的接口 ...
- .Net调用Java的实现方法
一. IKVM 1.1下载配置IKVM 1.1.1. 下载路径 http://www.ikvm.net/index.html 1.1.2. 设置路径 解压ikvm-0.42.0.3.zip,并将%IK ...
- AndroidJNI 调用JAVA(转)
转自:http://www.cnblogs.com/likwo/archive/2012/05/21/2512400.html 1. JNIEnv对象 对于本地函数 JNIEXPORT ...
- C#开发和调用Web Service
http://blog.csdn.net/h0322/article/details/4776819 1.1.Web Service基本概念 Web Service也叫XML Web Service ...
- ASP.NET调用Web Service
1.1.Web Service基本概念 Web Service也叫XML Web Service WebService是一种可以接收从Internet或者Intranet上的其它系统中传递过来的请求, ...
- C# 调用 Web Service
Web Service也叫XML Web Service WebService是一种可以接收从Internet或者Intranet上的其它系统中传递过来的请求,轻量级的独立的通讯技术.是:通过SOAP ...
随机推荐
- mysql索引之主键索引
MySQL目前主要有以下几种索引类型:1.普通索引2.唯一索引3.主键索引4.组合索引5.全文索引 二.语句 CREATE TABLE table_name[col_name data type] [ ...
- 2018-2019 ACM-ICPC, Asia Seoul Regional Contest
ProblemA Circuits Solved. 题意: 有$n$个矩形,可以放两条平行与$x$轴的线,求怎么放置两条无线长的平行于$x$轴的线,使得他们与矩形相交个数最多 如果一个矩形同时与两条线 ...
- jquery实现ajax跨域请求
1.跨域问题: 是因为浏览器的同源策略是对ajax请求进行阻拦了,但是不是所有的请求都给做跨域,像是一般的href属性,a标签什么的都不拦截. 如: 项目一:p1.html <body> ...
- python webdriver 测试框架-数据驱动json文件驱动的方式
数据驱动json文件的方式 test_data_list.json: [ "邓肯||蒂姆", "乔丹||迈克尔", "库里||斯蒂芬", & ...
- Puppeteer前端自动化测试实践
本篇内容将记录并介绍使用Puppeteer进行自动化网页测试,并依靠约定来避免反复修改测试用例的方案.主要解决页面众多时,修改代码导致的牵连错误无法被发现的运行时问题.文章首发于个人博客.对前端感兴趣 ...
- log parser分析windows日志
首先将windows安全日志导出,步骤如下: 运行eventvwr.msc命令,打开windows日志,如下图,将所有事件另存为: 保存完之后是一个.evtx格式的文件,将使用log parser分析 ...
- 20145318《网络对抗》逆向及Bof基础
实践目标 本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串. 该程序同时包含另一个代码片段,getShe ...
- InstallShieldpro2015 使用教程
1.下载地址:http://pan.baidu.com/s/1pLDCh3H ,如果网盘链接失效,请联系我. 2.解压后双击 3.安装完毕后,运行InstallShieldpro2015,会出现如下提 ...
- hyper-v安装虚拟机ubuntu 18.04 64bit后无法使能增强模式怎么办
1.获取脚本来使能增强模式 $ sudo apt-get update $ sudo apt install git $ git clone https://github.com/jterry75/x ...
- 【转载】解决telnet无法连接 Connection refused
原文:解决telnet无法连接 Connection refused telnet协议是TCP/IP协议族中的一员,是Internet远程登陆服务的标准协议和主要方式.它为用户提供了在本地计算机上完成 ...