接上篇《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. 第8章 用户模式下的线程同步(2)_临界区(CRITICAL_SECTION)

    8.4 关键段(临界区)——内部也是使用Interlocked函数来实现的! 8.4.1 关键段的细节 (1)CRITICAL_SECTION的使用方法 ①CRITICAL_SECTION cs;   ...

  2. text

    链接: 初识 TextKit 如何实现自己没实现过的需求之文本动画

  3. PHP & Delphi 語法

    明 C(区分大小写) Delphi(不区分大小写) PHP(区分大小写) 整型变量的定义 1 2 3 4 5 6 7 char a = 'a';         /* 8位有符号*/ int a=10 ...

  4. centos 命令集合

    链接: http://www.cnblogs.com/zitsing/archive/2012/05/02/2479009.html http://www.centoscn.com/CentOS/he ...

  5. WPF DatePicker默认显示当前日期

    WPF的日历选择控件默认为当前日期,共有两种方法,一种静态,一种动态. 静态的当然写在DatePicker控件的属性里了,动态的写在对应的cs文件里,具体请看下面.     1.方法一:     my ...

  6. Apache Rewrite 拟静态配置

    1.mod_rewrite 简介和配置 Rewirte主要的功能就是实现URL的跳转和隐藏真实地址,基于Perl语言的正则表达式规范.平时帮助我们实现拟静态,拟目录,域名跳转,防止盗链等 2.mod_ ...

  7. 51nod lyk与gcd

    1678 lyk与gcd 基准时间限制:2 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 这天,lyk又和gcd杠上了.它拥有一个n个数的数列,它想实现两种操作. 1:将  ai  ...

  8. sobel算子

    #1,个人理解 网上查了很多资料,都说sobel算子是用来检测边缘的,分别给了两个方向上的卷积核,然后说明做法,就说这就是sobel算子.对于我个人来说,还有很多不明白的地方,所以理清下思路. #2, ...

  9. velocity模板引擎学习(3)-异常处理

    按上回继续,前面写过一篇Spring MVC下的异常处理.及Spring MVC下的ajax异常处理,今天看下换成velocity模板引擎后,如何处理异常页面: 一.404错误.500错误 <e ...

  10. JAVA JPA - 示例用法

    JPA(Java Persistence API)是JSR(Java Specification Requests)的一部分,定义了一系列对象持久化的标准,目前实现这一规范的产品有Hibernate. ...