旧话重提:IIS将http强制https访问的正确方法

我以前写过《DTcms4/5中使用HttpModule将http访问301重定向到https》,也写过《使用Certify来自动申请并配置Let’s Encrypt免费SSL证书到IIS8》都提到了如何将IIS的http访问强制为https,如果你现在搜索.net强制https访问,或者iis强制https等关键词,会看到很多错误的指导。

常见问题1:要求SSL

比方说开启“ 要求SSL ”,然后用 403 的html(在 C:\inetpub\custerr\目录下,注意语言版本)重定向js代码,这个千万别用了。

<script type="text/javascript">  
    var url=window.location.href;  
    url=url.replace("http:","https:")  
    window.location.replace(url);
</script>

常见问题2:图形化设置IIS的URL重写工具

还有些介绍安装微软IIS的URL重写工具的,讲了半天一堆截图,操作下来因为版本不一样,还不一定成功,你直接按照我的方法,使用Web Platform Installer安装2.0版本:如下图。

然后也不要去IIS的管理器一个个站点去设置了,只需要在Web.config里面的 <system.webServer>节点内增加如下代码即可:

    <rewrite>
      <rules>
        <rule name="HTTP to HTTPS redirect" stopProcessing="true">
          <match url="(.*)" />
          <conditions>
            <add input="{HTTPS}" pattern="off" ignoreCase="true" />
          </conditions>
          <action type="Redirect" redirectType="Found" url="https://{HTTP_HOST}/{R:1}" />
        </rule>
      </rules>
    </rewrite>

如果需要开启HSTS请用以下代码,首次访问不用https,但之后都会强制使用了,所以建议开启!

           <rules>
                <rule name="redirect to HTTPS" enabled="true" stopProcessing="true">
                    <match url="(.*)" />
                    <conditions>
                        <add input="{HTTPS}" pattern="^OFF$" />
                    </conditions>
                    <action type="Redirect" url="https://{HTTP_HOST}/{R:1}"
                    redirectType="Permanent" />
                </rule>
            </rules>
            <outboundRules>
                <rule name="Add Strict-Transport-Security when HTTPS" enabled="true">
                    <match serverVariable="RESPONSE_Strict_Transport_Security"
                        pattern=".*" />
                    <conditions>
                        <add input="{HTTPS}" pattern="on" ignoreCase="true" />
                    </conditions>
                    <action type="Rewrite" value="max-age=31536000" />
                </rule>
            </outboundRules>

常见问题3:WebApi还在用自己写的filter重定向

这个方法未必不可以,但我不认为最优。我也在用,以下代码的BaseSystemInfo.ForceHttps是我的一个系统参数,可以自行切换,如果没有安装URL重写工具,本地测试可以http。

但有了URL重定向,这个重定向代码就不会执行了。

public override void OnAuthorization(HttpActionContext actionContext)
        {
            //先检查是否:强制https访问
            var request = actionContext.Request;
            if (BaseSystemInfo.ForceHttps && request.RequestUri.Scheme != Uri.UriSchemeHttps)
            {
                var html = "<p>Https is required</p>";
                if (request.Method.Equals(HttpMethod.Get) || request.Method.Equals(HttpMethod.Head))
                {
                    actionContext.Response = request.CreateResponse(HttpStatusCode.Found);
                    actionContext.Response.Content = new StringContent(html, Encoding.UTF8, "text/html");
                    //重定向
                    var httpsNewUri = new UriBuilder(request.RequestUri);
                    httpsNewUri.Scheme = Uri.UriSchemeHttps;
                    httpsNewUri.Port = 443;
                    actionContext.Response.Headers.Location = httpsNewUri.Uri;
                }
                else
                {
                    actionContext.Response = request.CreateResponse(HttpStatusCode.NotFound);
                    actionContext.Response.Content = new StringContent(html, Encoding.UTF8, "text/html");

                    //重定向
                    var httpsNewUri = new UriBuilder(request.RequestUri);
                    httpsNewUri.Scheme = Uri.UriSchemeHttps;
                    httpsNewUri.Port = 443;
                    actionContext.Response.Headers.Location = httpsNewUri.Uri;
                }
            }
        }

好了,看完这篇文字,你不要再去搜索查找可行的IIS强制https的ssl证书访问了。

启用IIS Express SSL(Https)的注意事项

2年前搞国外的信用卡支付对接,必须用SSL方式调用第三方支付公司的接口,本地调试需要启用IIS Express的SSl,最近又搞类似需要SSL的项目,忘记怎么设置的了,本以为直接将原来的http后面加个s,居然不行。费了点时间找到原因:IIS Express 的 SSL 的端口默认是从 44300 开始的。可以自己修改最后两位。

使用Certify来自动申请并配置Let’s Encrypt免费SSL证书到IIS8

越来越多的网站在启用HTTPS,也就是SSL加密通讯连接访问。特别是去年开始BAT在国内的推广和应用要求。要知道部署发布一个苹果iOS企业应用,下载服务器就必须使用HTTPS协议。

我去年做了美国的信用卡交易系统对接,调用信用卡公司的接口必须通过公网的支持TLS1.1以上的服务器,还需要IP白名单。可以看出在互联网交易支付方面HTTPS多么重要。

言归正传,SSL证书通常是需要付费的,但我们今天找到一个非常牛逼的全球通用的免费SSL项目:Let’s Encrypt – Free SSL/TLS Certificates,网址为:https://letsencrypt.org/

Let’s Encrypt 是国外一个公共的免费 SSL 项目,由 ISRG 联手组成证书颁发机构,可以签发免费 SSL/TLS 证书。ISRG(Internet Security Research Group,互联网安全研究小组)是一个关注网络安全的公益组织,其赞助商从非商业组织到财富100强公司都有,包括 Mozilla,Akamai,思科,Facebook,密歇根大学等等。

Let’s Encrypt是为普及 HTTPS 而发起的,它推动了基础 DV SSL 证书的普及。其证书已经被 Mozilla、Google、Microsoft 和 Apple 等主流浏览器支持,只需要 web 服务器配置好 HTTPS 证书,浏览器会在加载时验证 web 服务器 HTTPS 证书是否有效。随着 https 的普及,Let’s Encrypt 目前已成为全球最受欢迎的免费 SSL 证书签发机构

Let’s Encrypt的优点有2个:完全免费,避免 ISP 劫持;申请速度快、无需注册账户

但是有两点也需要注意:
1、Let’s Encrypt 的基础 DV SSL 证书,只提供了数据加密,不验证身份,无法向用户证明网站的所有者。但即使这样也满足了基本需要了。
2、它一次只会颁发 3 个月有效期的证书,到期之后需要自己再续上(仍然是免费的)。不过我们可以用下面要介绍的工具Certify来自动续约。

Certify 是一个可以自动续订 Let’s Encrypt 颁发证书的第三方 GUI 软件(图形界面工具),使用它可以自动配置、创建和自动续订证书,并且到快要续订的时候会自动发邮件通知我们。
官网地址:https://certify.webprofusion.com/
使用时,首先将Certify下载到服务器上并安装。注意其依赖 Microsoft .NET Framework 4.5,Windows 2012 R2默认安装.NET 4.5,Windows 2008 R2等低版本安装时会提示。
第一次启动程序时会弹出对话框让我们填写个邮箱地址,等证书快要过期的时候我们会收到续订证书的提醒邮件。这里我们填上常用的 email 地址,注意这里不认QQ的数字前缀邮箱。

进入以后,全部图形化界面,操作很简单,流程如下:

点击“新建证书”按钮,certify 会自动扫描 IIS 中的站点,选择我们要申请证书的域名。完毕后点击“保存”按钮进行保存。保存后点击“请求证书”按钮获取证书。在申请的同时,Certify 会在网站根目录下生成 .well-known 文件夹(我们可以稍后把这个目录给删掉,以保持网站目录干净。),并自动配置 web.config,自动验证证书。完全不用我们干预。待其执行完毕后,返回 Certify 的首页面可以看到站站点已经成功使用了 Let’s Encrypt 的证书了。

有一点需要注意,免费版的Certify只支持5个站点。

证书获取之后,还有一件重要的事情,就是限制只允许HTTPS访问(如下图),同时要在IIS设置HTTP自动转向到HTTPS,这块内容请自行搜索,特别是针对C#.NET应用,web.config就能搞定,URL重写都不用,也不用改403的javascript自动转向。