对有ssl验证的Soap请求进行提交和获取响应

最近一段时间做了一个项目,需要将生成的soap请求的xml字符串提交给服务端地址,然后将返回的soap响应进行分析判断得到结果。这其中需要在请求的同时附上证书进行验证。

其实这个功能实现起来不是很难,但是在研究的过程中有几个小问题却让我多费了好几个脑细胞,在此记录下,为自己和博友们做一下小小的提醒。

其中主要出现的问题有以下几点:

  •   报WebException异常: The request was aborted: Could not create SSL/TLS secure channel.
  •   报服务器内部500错误

这两个问题主要在代码中哪些部分会出现呢,就去代码中看看。

OK,先上段代码

 1         /// <summary>
 2         /// 进行进行ssl验证的服务器进行soap请求
 3         /// </summary>
 4         /// <param name="tokenId">需要生成soap请求的参数1</param>
 5         /// <param name="secureCode">需要生成soap请求的参数2</param>
 6         /// <returns>soap请求的响应内容</returns>
 7         public string SoapRequest(string tokenId, string secureCode)
 8         {
 9             string url = "https://[The request url for your soap request]";
10             string soapAction = "[the action name]";
11
12             // GenerateSoapContent 方法用来构造Soap的XML请求
13             string soapRequest = GenerateSoapContent(tokenId, secureCode);
14
15             // 这句话用来调用ValidateFbCertificate方法,让远程ssl证书验证设为成功
16             ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(ValidateFbCertificate);
17
18             // 设置安全协议类型,这个需要对应具体需求
19             ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
20
21             HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
22             webRequest.Headers.Add("SOAPAction", soapAction);
23             webRequest.ContentLength = soapRequest.Length;
24             webRequest.Method = "POST";
25             webRequest.ProtocolVersion = HttpVersion.Version10;
26
27             // 将证书加入web请求中
28             X509Certificate2 cert2 = new X509Certificate2(Server.MapPath("pfx或者p12格式的文件名"), "证书密码", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet);
29             webRequest.ClientCertificates.Add(cert2);
30
31             using (Stream requestStream = webRequest.GetRequestStream())
32             {
33                 byte[] paramBytes = Encoding.UTF8.GetBytes(soapRequest);
34                 requestStream.Write(paramBytes, 0, paramBytes.Length);
35                 requestStream.Close();
36             }
37
38             WebResponse webResponse = null;
39             try
40             {
41                 webResponse = webRequest.GetResponse();
42                 using (StreamReader myReader = new StreamReader(webResponse.GetResponseStream(), Encoding.UTF8))
43                 {
44                     string response = myReader.ReadToEnd();
45                     myReader.Close();
46                     return response;
47                 }
48             }
49             catch (Exception ex)
50             {
51                 throw ex;
52             }
53         }
54
55         /// <summary>
56         /// Generate the soap request
57         /// </summary>
58         /// <param name="userId">the token Id</param>
59         /// <param name="secureCode">the secure code</param>
60         /// <returns>the request string</returns>
61         string GenerateSoapContent(string userId, string secureCode)
62         {
63             return "<?xml version=\"1.0\" encoding=\"UTF-8\" ?><soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:vip=\"https://schemas.symantec.com/vip/2011/04/vipuserservices\">"
64                 + "<soapenv:Header/>"
65                 + "<soapenv:Body>"
66                 + "<vip:AuthenticateUserRequest>"
67                 + "<vip:requestId>1323</vip:requestId>"
68                 + "<vip:userId>" + userId + "</vip:userId>"
69                 + "<vip:otpAuthData>"
70                 + "<vip:otp>" + secureCode + "</vip:otp>"
71                 + "</vip:otpAuthData>"
72                 + "</vip:AuthenticateUserRequest>"
73                 + "</soapenv:Body>"
74                 + "</soapenv:Envelope>";
75         }

以上是基本已经将问题解决的代码。

在代码中,当16,19行代码未写,可能就会出现异常: “The request was aborted: Could not create SSL/TLS secure channel.”。当28,29行未写,那肯定会出现该异常。

在出现500内部错误时,我一直以为是服务器端的方法出现了错误,直到用php的curl执行soap请求成功返回结果,才发现是一个小小的问题导致了这个“严重”的麻烦。具体原因是因为在写soap请求文本时,原来的GenerateSoapContent方法是如下写法:

 1         /// <summary>
 2         /// Generate the soap request
 3         /// </summary>
 4         /// <param name="userId">the token Id</param>
 5         /// <param name="secureCode">the secure code</param>
 6         /// <returns>the request string</returns>
 7         string GenerateSoapContent(string userId, string secureCode)
 8         {
 9             StringBuilder builder = new StringBuilder();
10             builder.AppendLine("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>");
11             builder.AppendLine("<S:Envelope xmlns:S=\"http://schemas.xmlsoap.org/soap/envelope/\" >");
12             builder.AppendLine("    <S:Body>");
13             builder.AppendLine("        <AuthenticateUserRequest xmlns=\"https://schemas.vip.symantec.com\">");
14             builder.AppendLine("            <requestId>" + ((Int32)(new Random().NextDouble() * 1000) + 1) + "</requestId>");
15             builder.AppendLine("            <userId>" + userId + "</userId>");
16             builder.AppendLine("            <pin></pin>");
17             builder.AppendLine("            <otpAuthData>");
18             builder.AppendLine("            <otp>" + secureCode + "</otp>");
19             builder.AppendLine("            </otpAuthData>");
20             builder.AppendLine("        </AuthenticateUserRequest>");
21             builder.AppendLine("    </S:Body>");
22             builder.AppendLine("</S:Envelope>");
23             return builder.ToString();
24         }

看出与最上面的方法有什么不同了吗?是的,StringBuilder的AppendLine害了我,因为这样会在最终生成的soap字符串中添加了“\r\n"字符,那传到服务器端就不会被服务器端方法识别为soap的xml格式,就会抛出异常。

其实这些都不是什么难以解决的问题,主要是因为自己不注意。在此留下这篇文章,为后来人提供些许帮助。

时间: 2024-10-05 10:06:37

对有ssl验证的Soap请求进行提交和获取响应的相关文章

[转]C#通过Http发送Soap请求

/// <summary>        /// 发送SOAP请求,并返回响应xml        /// </summary>        /// <param name="url">请求地址</param>        /// <param name="datastr">SOAP请求信息</param>        /// <returns>返回响应信息</retur

Jmeter学习及使用(二)Http请求和soap请求(最基础运用)

启动Jmeter后, 在Test plan下创建线程组: 1. 创建线程组(Thread Group) 在Thread Group界面,有一些线程的设置需要了解,如图: 下面就可进行Http/Soap请求测试 测试的数据: 接口地址:http://apis.juhe.cn/mobile/get 返回格式:json/xml 请求方式:get 请求示例:http://apis.juhe.cn/mobile/get?phone=13429667914&key=您申请的KEY 一. 测试Http请求 以

用post来进行Soap请求

最近调了一个Soap请求C# webservice的项目.网上坑不少. 使用原生的SoapClient库请求也是失败.只好用post来进行模拟了.代码贴出来,给大家参考一下. <?php namespace App\Services\Proxy; use Log; class Crm { private $host; private $namespace; private $app_secret; private $username; private $values; public functi

java 查看SOAP请求报文

1 log.info("ESB 请求URL = " + cachedEndpoint.toString());//打印SOAP请求报文 add by LinJC on 20170120 2 java.lang.Object _resp = _call 3 .invoke(new java.lang.Object[] {data }); 4 log.info("ESB 请求XML = " + _call.getMessageContext().getRequestMe

最简单易懂的webService客户端之soap请求

代码准备: 1.网络上有提供一些免费的服务器测试地址,可以上这里找一找:https://my.oschina.net/CraneHe/blog/183471 2.我选择了一个翻译地址:http://www.webxml.com.cn/WebServices/TranslatorWebService.asmx 2.1打开之后看到该地址下有一个方法: 2.2点击进入,网站会提供该方法的客户端请求xml格式: 2.3,这个红框部分就是我们要的,将它写入代码,就可以完成请求了. 注意:以上还是获取soa

Web Service之Soap请求响应内容中文编码解密

java模拟Soap请求测试Web Service接口,发现Web Service响应内容中的中文竟然是编码格式.比如: 中文:退保成功 Soap中文编码:退保成功 我仔细分析后发现,退编码实际上就是Unicode编码的Soap版,正规的Unicode编码是\u9000,Soap改成自己的格式&#x[4位内容];格式. 还有其他的比如: 换行,Soap编码: 单引号,Soap为转换为html编码:&apos; 与号,Soap为转换为html编码:& 小于号,Soap为转换为html

去除CAS4.0的 SSL验证,和3.5.2是一样的

下载了CAS4.0,改变比较大,计划慢慢研究,慢慢更新. 按以下方法去除CAS4.0的SSL强制要求,这和3.5.2是一样的,FT,明明去除了,但提示还在,一直以为没修改成功. 修改第一处: cas/WEB-INF/deployerConfigContext.xml <bean class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler"p

Java发布webservice应用并发送SOAP请求调用

webservice框架有很多,比如axis.axis2.cxf.xFire等等,做服务端和做客户端都可行,个人感觉使用这些框架的好处是减少了对于接口信息的解析,最主要的是减少了对于传递于网络中XML的解析,代价是你不得不在你的框架中添加对于这些框架的依赖.个人观点是:服务端使用这些框架还行,如果做客户端,没必要使用这些框架,只需使用httpclient即可. 一.创建并发布一个简单的webservice应用 1.webservice 代码: import javax.jws.WebMethod

根据wsdl生成soap请求格式

本文链接:https://blog.csdn.net/a_Little_pumpkin/article/details/84725118根据wsdl文件如何生成soap请求的格式呢?使用最方便的工具SoapUI下载地址:http://sourceforge.net/projects/soapui/files/ [img]http://dl2.iteye.com/upload/attachment/0109/6115/374fc0b7-0216-3042-864e-cdb0448a8bac.jpg