关于给WP推送通知启用HTTPS验证的细节

关于整个推送机制, 如何建立推送通道,在服务端和客户端的代码实现,互联网以及MSDN已经有无数中英文资料和示例了。然而,如果希望启用HTTPS推送,相关的资料就很少了。在这篇文章中我们主要希望谈论一下关于Windows Phone中为推送通知Push Notification启用HTTPS验证的一些所需要注意到的细节。

在默认情况下,Windows 8 store app的所有推送都是启用了HTTPS验证的,但是对于WP来说,默认情况下所有推送通道都是基于安全性较低的非加密通道HTTP,所以出于信息安全的考虑,我们推荐开启为推送通知开启HTTPS。除此之外,启用推送HTTPS验证的好处在于,能够解除每个推送通道每天500条推送的上限。而且最主要的是,除了开发商需要花钱购买一个受信任的证书以及一个WP开发者账户,一切都是免费的。

关于HTTP通讯的500条上限的解释,MSDN中的原文是这样的:

There is no daily limit on the number of push notifications an authenticated web service can send. Unauthenticated web services, on the other hand, are throttled at a rate of 500 push notifications per subscription, per day.

很多开发者对于这里关于“per subscription, per day”的描述有一些理解偏差。实际情况是,基于对一个APP来说,在一个WP设备上,只能申请到一个Push Notification Channel (“subscription”),而每台不同设备的APP所能申请到的Channel Uri都是独特的,那么这里的限制就是对于这一个Channel Uri,只能够推送500个。所以说,对于每一个APP,HTTP推送在每个单独设备上的每日上限是500个,APP互相之间额度也不共享不冲突。

开启HTTPS验证推送通知的步骤

1. 向第三方证书机构购买证书。

以下是Windows Phone所信任的根证书列表,注意第一个链接是关于WP7的,而WP8和Windows 8的信任根证书列表相同:

SSL root certificates for Windows Phone OS 7.1

https://msdn.microsoft.com/en-us/library/windowsphone/develop/gg521150(v=vs.105).aspx

Windows and Windows Phone 8 SSL Root Certificate Program (Member CAs)

https://social.technet.microsoft.com/wiki/contents/articles/14215.windows-and-windows-phone-8-ssl-root-certificate-program-member-cas.aspx

以我们在进行测试的时候购买的证书为例,通过digicert购买了一个Wildcard SSL Certificate,这类证书和最基本的Single-Name SSL Certificates区别在于,前者证书的关联域名允许使用通配符,如*.ranger.im,而后者必须是一个具体完整的域名。对于我们的HTTPS推送验证服务,证书种类没有影响。

关于申请证书,每个证书颁发机构都有完善的指导和服务,其中不少都有中国/中文的代理和客服,如verisign的中国代理https://verisign.itrus.com.cn/。在购买之前请同机构核实这个证书的信任链中是否有属于WP的根证书列表里。

在申请的过程中,通常第一步我们需要填写证书的Common Name / Subject Name,这里需要同您已经拥有的域名相一致,证书颁发机构会有一个认证的过程。同时,记住这个CN的值,这在我们之后的代码实现中非常重要。在最终的证书中,我们也能够通过Subject一栏来看到这个CN值。

2. 上传证书的公钥部分(.cer)。

通常最后我们获取到的证书容器是一个.pfx文件。PFX包含了证书的公钥和私钥,所以需要妥善保存。我们需要到处整个证书的公钥部分,通常以.cer形式的文件出现。我们访问任何https的网站的时候,都能够通过浏览器来很方便地获取到这个证书文件。

Windows Phone Dev Center - Dashboard - Account - MPN Certificate页面 ,能够上传和查看所关联的推送证书。比较遗憾的是当前还没有加入删除功能。上传完毕之后,这里会列举出证书的Subject Name CN,指纹码Thumbprint和过期时间。

3. 客户端实现

在WP APP的代码中,HTTPS的推送过程同普通的没有很大区别,客户端代码中申请推送通道的时候,需要作为HttpNotificationChannel Constructor (String channelName, String serviceName) 构造函数的第二个参数传入。然后在本地运行一下app,如果能够成功申请到HTTPS的channel uri,则表示整个过程都成功了。

这里值得一提的是,文档中并没有对第一个参数channelname作过多描述,但是根据我们的技术支持经验,如果我们的测试app原本使用了某个channel name,那么在之后准备开启https channel的时候,建议简单更新一下这个channel name名字,如把MyPushChannel改成MyPushChannelSSL。我们所碰到的一个案例就是没有及时更新channel name,客户端也能获得HTTPS channel URI,但是服务端往这个地址进行推送之后,会返回一个401错误 "401 - Unauthorized: Access is denied due to invalid credentials." "You do not have permission to view this directory or page using the credentials that you supplied"。通常来说用到这个channel name值的会有两处,一个是HttpNotificationChannel(channelName,serviceName)构造函数,另一个是HttpNotificationChannel.Find(channelName)静态函数。

4. 服务端实现

进行推送通知的服务端代码进行客户端验证的HTTPS POST操作我们这里就不详细列举了, 我们以.NET平台的HttpWebRequest对象为例,只需要为HttpWebRequest对象加入客户端私钥证书并提供证书密码,如request.ClientCertificates.Add(new X509Certificate2("[Path To Certificate]", "[Password]"));

5. 关于证书更新和过期

(2014/1/20补充)

这里需要补充一下最近一个合作伙伴遇到的比较尴尬的场景。该wp app之前启用了HTTPS push,但是证书最近过期了,结果在更新app的时候遇到了问题,唯一的解决方案就是购买或者续费一个新的证书并上传到WP store dashboard中,而且新证书的CN必须同原证书完全相同。这里我把关于推送证书更新和过期的一些未在官方文档中标明的内容总结一下:

  1. 商店-Dashboard-Account-MPN certificate界面会列出所有已上传的证书,并能够上传新证书,但是不能进行修改和删除操作。
  2. 如果一个WP app在商店中同推送证书作过关联,那么未来的任何一个版本更新的时候,都必须保证关联到一个有效期内的证书且CN一致。
  3. 换句话说,如果一个app绑定到了某个证书上,那么未来除非推送机制改变,则永远都必须确保这个证书可用且CN内容不变。
  4. 所以对于某个app的关联证书过期这样一个场景,只有一种选择:上传一个在有效期内的有相同CN值的新证书。

相关参考资料:

Setting up an authenticated web service to send push notifications for Windows Phone

https://msdn.microsoft.com/en-us/library/windowsphone/develop/ff941099(v=vs.105).aspx

Web service security for Windows Phone

https://msdn.microsoft.com/en-us/library/windowsphone/develop/gg521147(v=vs.105).aspx

No-quota push notifications using a root Certificate Authority

https://blogs.windows.com/windows_phone/b/wpdev/archive/2013/06/06/no-quota-push-notifications-using-a-root-certificate-authority.aspx

HttpNotificationChannel Constructor (String, String)

https://msdn.microsoft.com/library/windowsphone/develop/ff403009(v=vs.105).aspx

How To Send An Authenticated Message to the Windows Phone Push Notification Service

https://blogs.technet.com/b/speschka/archive/2012/06/04/how-to-send-an-authenticated-message-to-the-windows-phone-push-notification-service.aspx

Windows Phone Push Notifications: Frequently Asked Questions

https://blog.mjfnet.com/2012/03/19/windows-phone-push-notifications-frequently-asked-questions/

-Ranger