接上篇《WebApi服务URI加密及验证的两种方式》,在实际开发中,仅对URI进行加密是不够的,在传输层采用SSL加密也是必须的。

如果服务寄宿于IIS,那对传输层加密非常简单仅需要配置一下项目属性开启SSL即可,所用的证书也是IIS帮你搞定(默认443端口证书),基本就是傻瓜式配置后即可强制使用HTTPS访问资源。

而在Self Host WebApi服务中使用传输层SSL加密,则需要自己手动绑定服务器端的证书,并且在服务器端对客户端Request验证其是否为HTTPS访问方式;在客户端也需要对原有(上一篇)代码做一些小小的补充。

服务端:

服务端的工作分为服务器证书绑定,以及WebApi自宿主代码修改。

1:服务器证书绑定

关于如何在服务器端绑定一个自签名的证书,网上有很多资料,这里只是简要记录一下要点。因为认证机构颁发的证书都需要钱,开发测试过程中不需要购买证书,只需要在测试端口绑定一个自签名证书即可。

step 1: 找一个可用的证书指纹

    我是在开发环境下的IIS(服务器证书)中找的一个已安装的证书,即IIS Express Development Certificate。找到详细信息中的指纹(一串16进制加密数字),复制备用;

step 2:拿到项目的UUID,我就用的sln文件中该项目的UUID;

step 3:以管理员权限运行cmd,为指定端口绑定一个自签名的证书

    netsh命令不再详述,只给出这里需要用到得3个命令:

1)端口7777绑定证书:netsh http add sslcert ipport=0.0.0.0:7777 certhash=8239ff15609faaa25f55d07931e78bee96bbXXXX appid={FAE04EC0-301F-11D3-BF4B-00C04F79EFBC},运行后如果绑定成功,将提示“成功添加SSL证书”;

      其中,certhash即step1复制的指纹,appid即step2的uuid;  

    2)端口7777证书删除:netsh http delete sslcert ipport=0.0.0.0:7777,运行成功后如果成功删除该端口上绑定的证书,则将提示“成功删除SSL证书”;

    3)查看SSL证书:netsh http show sslcert,执行后将列出机器上所有端口绑定的证书,找到端口7777的证书,将能看到证书哈希及应用程序ID信息,与之前添加的一致。

2:Web API 自宿主服务器端代码修改

服务器端的代码修改包括:1)uri的scheme验证,确保资源访问必须采用ssl加密;2)自宿主服务器启动监听uri改为https字头。

scheme验证仍然采用与上篇文章相同的方法,即实现一个新的HttpMessageHandler,并将其注入到消息处理管道中:

     public class HttpsGuard : DelegatingHandler
     {
         protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
         {
             if (!request.RequestUri.Scheme.Equals(Uri.UriSchemeHttps, StringComparison.CurrentCultureIgnoreCase))
             {
                 var response = new HttpResponseMessage(HttpStatusCode.BadRequest)
                 {
                     Content = new StringContent("Https is required for security reason")
                 };
                 return Task.FromResult(response);
             }
             return base.SendAsync(request, cancellationToken);
         }
     }

修改Startup的Configuration,将上面的HttpMessageHandler注入:

         public void Configuration(IAppBuilder app)
         {
             // Configure Web API for self-host.
             var config = new HttpConfiguration();
             config.Routes.MapHttpRoute(
                 name: "DefaultApi",
                 routeTemplate: "api/{controller}/{action}/{param}",
                 defaults: new { id = RouteParameter.Optional }
             );
             //注入response handler
             config.MessageHandlers.Add(new ResponseHandler());
             //注入httpmessagehandler用于验证request是否均采用SSL加密传输
             config.MessageHandlers.Add(new HttpsGuard());
             //允许WebApi的跨域访问 - 测试条件下允许所有域的跨域访问
             var cors = new EnableCorsAttribute("*", "*", "*");
             config.EnableCors(cors);

             app.UseWebApi(config);
         }

服务器启动则改为如下:

 ).Uri;

 var server = WebApp.Start<Startup>(url: urlBase.AbsoluteUri);

以上三部分修改完成后,对web api服务端代码的修改完毕,可以启动服务,正常开始监听本地7777端口。此时如果在浏览器中访问,则会提示证书失效,是否继续访问等等大家熟悉的场景。

客户端:

如何远程调用SSL通信加密后的Web Api资源

以上步骤完成后,直接在客户端经由上一篇所重写的HttpClient访问加密后的资源,一般会报一个“基础连接已经关闭: 未能为 SSL/TLS 安全通道建立信任关系。”这样的错(我的VS是中文版的),产生这个错误的原因是因为服务器上7777端口绑定的证书错了(因为我们搞了个自签名的测试证书),或者证书过期了啊什么的,也都会出现这个问题,总之就是证书不受信任了。绑定一个有效的受信证书就不会有这个问题了(没试过)。这里为了方便开发及测试,需要对客户端代码做如下修改,目的就是不验证证书的有效性,即接受所有证书的认证。

新增如下方法:

private static bool AcceptAllCertifications(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certification, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors)
{
        return true;
}

在base.SendAsync(request, cancellationToken)之前,调用下这个方法:

ServicePointManager.ServerCertificateValidationCallback += RemoteCertificateValidate;

即可。

或者不需要新增这个方法,直接在base.SendAsync(request, cancellationToken)之前新增一句:ServicePointManager.ServerCertificateValidationCallback += delegate { return true; };即可,简单粗暴,信任所有证书。

以上步骤完成之后,即可通过

var myResponse = myClient.GetAsync("https://192.168.1.166:7777/api/test/GetUser/id=123123&name=jiakai").Result;

类似的URI访问服务器资源。经测试,SSL加密后的客户端-服务器通信消息,在fiddler中无法抓取到包(网上有fiddler抓取https通信包的各种方法,不较真了)。

经过上篇与本篇的通信加密方法,即可建立一套基本的web api资源安全通信方式,可满足通常情况下的通信安全需求。

Self Host WebApi服务传输层SSL加密(服务器端+客户端调用)的更多相关文章

  1. 驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接

    由于项目中必须得用JDK6来作为Java环境,于是连接SQLServer时出现了com.microsoft.sqlserver.jdbc.SQLServerException: 驱动程序无法通过使用安 ...

  2. JDBC连接数据库遇到的“驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接。

    要从旧算法列表中删除3DES: 在JDK 8及更早版本中,编辑该 /lib/security/java.security文件并3DES_EDE_CBC从jdk.tls.legacyAlgorithms ...

  3. (4.22)Microsoft 管理控制台启用 SSL 加密的 SQL Server 实例

    如何通过使用 Microsoft 管理控制台启用 SSL 加密的 SQL Server 实例 关键词:MSSQL加密,sql server加密,sql server客户端与服务器传输内容加密 转自:h ...

  4. MSSQL - 最佳实践 - 使用SSL加密连接

    MSSQL - 最佳实践 - 使用SSL加密连接 author: 风移 摘要 在SQL Server安全系列专题月报分享中,往期我们已经陆续分享了:如何使用对称密钥实现SQL Server列加密技术. ...

  5. EXCHANGE 2013 TLS传输层安全

    默认情况下,SMTP流量是不被加密的,这就导致在公网上进行邮件沟通就像是在广播一样,任何人拦截到该邮件都可以轻而易举的读取其内容.但是现实场景中有许多敏感信息是通过邮件来进行发送的,所以其中一种保护邮 ...

  6. Filebeat与Logstash配置SSL加密通信

    为了保证应用日志数据的传输安全,我们可以使用SSL相互身份验证来保护Filebeat和Logstash之间的连接. 这可以确保Filebeat仅将加密数据发送到受信任的Logstash服务器,并确保L ...

  7. 如何解决无法通过SSL加密与SQLServer建立连接

    在部署项目时,经常会遇到驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接,错误:Java.lang.RuntimeException: Could not gene ...

  8. 在SuperSocket中启用TLS/SSL传输层加密

    关键字: TLS, SSL, 传输层加密, 传输层安全, 证书使用, X509Certificate SuperSocket 支持传输层加密(TLS/SSL) SuperSocket 有自动的对TLS ...

  9. SSL&TLS传输层加密协议实现图解--(重要)

    一.SSL&TLS 1.SSL:Secure Sockets Layer ,加密套接字协议层 1)SSL是为网络通信提供安全及数据完整性的一种安全协议,在传输层对网络连接进行加密 Secure ...

随机推荐

  1. AC日记——数1的个数 openjudge 1.5 40

    40:数1的个数 总时间限制:  1000ms 内存限制:  65536kB 描述 给定一个十进制正整数n,写下从1到n的所有整数,然后数一下其中出现的数字“1”的个数. 例如当n=2时,写下1,2. ...

  2. 在Flex4中嵌入字体

    如果要使用的字体不是系统字体,可以把字体嵌入到Flash中,然后引用该字体.不过字体文件一般都比较大,慎重使用该功能. 官方例子 http://help.adobe.com/en_US/flex/us ...

  3. [No000055]教你早晨清肠、除口臭、色斑、大肚腩

    [长生不老的秘诀] 释.道.医三家有个共同的秘诀:"要叫人不死. 肠中须无屎". 佛家除要求人们戒杀吃素外,还认为早饭是天食,中饭是人食,晚饭是鬼食. 因此,为了身体健康,不妨碍修 ...

  4. [No000019]不想背单词?看看游戏能否帮你

  5. 对于多个列的转行(一个值均匀分布在两个列中),对于个别字段通过取别名,join方式解决。

    例如,这个表的结构: select r.* from RPDATA2016 r WHERE r.data_bbid='HY052' 如图 对于最后两列,如果是字符类型,会存在倒数第二列,是数字类型,会 ...

  6. HTML 学习笔记 JavaScript(简介)

    JavaScript 是世界上最流行的编程语言. 这门语言可用于HTML和web 更可广泛用于服务器.PC.笔记本电脑.平板电脑和智能手机等设备. JavaScript是脚本语言 JavaScript ...

  7. 树莓派B+安装archlinux arm版

    按Archlinux官网操作而来,如有疑问参照官网:http://archlinuxarm.org/platforms/armv6/raspberry-pi 以我自己安装过程举例,我的SD卡挂载在ub ...

  8. Linux 网络编程详解八

    TCP/IP协议三次握手机制 TCP/IP是全双工通道,两端都可以读写,三次握手机制就是验证TCP/IP是否是全双工通道 1.客户端调用connect()函数,阻塞客户端进程,客户端向服务器发送数据包 ...

  9. iptables实现负载均衡

    例子: iptables -t nat -A PREROUTING -d 10.192.0.65/32 -p tcp -m tcp --dport 8080 -m statistic --mode n ...

  10. FineUI小技巧(4)关闭窗体那些事

    前言 FineUI中的Window控件常用作选择.新增或编辑内容.而关闭Window控件却有很多技巧,了解这些技巧有助于项目的快速开发. 如何关闭Window控件 第一个问题就是如何关闭Window控 ...