The Push Notification Service is a cool feature of Windows Phone that lets you do things like send toast messages, update a Live Tile, etc. for your Windows Phone application. You can use the service without any additional transmission security protocols, but if you do you are limited to a maximum of 500 messages per day. If you use SSL to set up a mutually authenticated session to the Push Notification Service however, you can send an unlimited number of messages. This makes securing your conversation that much more appealing. The actual process for doing so is unfortunately documented about as poorly as anything I've ever seen. Fortunately the social forums in the Windows Phone App Hub are quite useful so you can piece it together from reading through them. To save you the time though of trying to hunt down all of the pieces needed to do this, I thought I would bring it all together here in one simple document. You know, kind of like the product team should have done. 🙂 So here goes:
- You can read about the requirements for the certificate that's used for establishing this secure communication here: http://msdn.microsoft.com/en-us/library/ff941099(v=vs.92). To make it simple though, I found that if you have an SSL certificate from one of the supported certificate authorities, it works just fine. To see the list of supported certificate authorities, see here: http://msdn.microsoft.com/en-us/library/gg521150(v=vs.92).
- You need to take this certificate and upload it to the App Hub. You don't need the PFX with the private key, just the public version of the certificate (i.e. the .cer file). To upload it, sign into the App Hub, sign-in and then click on your account name in the upper left corner. When you go into the account management page you will see a link called Certificates under the My Account banner. Click on that and follow the instructions there to upload the certificate.
- In your Windows Phone application you create a HttpNotificationChannel class instance. When you create the new HttpNotificationChannel, use the common name (CN) of the SSL certificate as the second parameter for the new channel. You can find the common name of your certificate by double-clicking on the .cer file top open it, click on the Details tab, and then click on the Subject property. You will see values displayed in the window below and the first one should be something like "CN = www.contoso.com"; you want to use just the "www.contoso.com" in this example. So when you created your new channel it would look something like this: pushChannel = new HttpNotificationChannel("myChannelName", "www.contoso.com");
- NOTE: If you have already created channels for different devices, then you will need to find your channel using the HttpNotificationChannel.Find method, then .Close and .Dispose the channel. Then you need to recreate it so you can associate your common name with the connection.
- Where run your server side code, you need to install the certificate, including the private key (so the .pfx file). You also need to ensure that the account for your application pool has access to the private keys for that certificate. To do that, open the MMC tool and add the Certificates snap-in for the Local Computer. After you've installed your certificate into the Personal node, right-click on the certifcate in the MMC and select All Tasks…Manage Private Keys. You then need to add the account for the application pool your application is using and grant it at least Read rights to the keys.
- NOTE: If you are using the new built in accounts in IIS 7.5, like ApplicationPoolIdentity, then you need to grant access to IIS apppool\ASP.NET v4.0, where “ASP.NET v4.0” is the name of your app pool.
- In the code where you are sending the message to the Push Notification Service you need to add the certificate to the HttpWebRequest object. You would typically do this by opening up the X509 Store, getting the certificate collection for the My store, doing a Find on the collection by thumbprint, where you need to copy and paste the certificate's thumbprint from the certificate properties to your code, and then using the first certificate in the collection it returns (i.e. myCollection). Once you have the certificate you can add it to your request like this: myRequest..ClientCertificates.Add(mySslCertificate);
The other important things to note:
- Your certificate that you upload in only used for four months. If you don't submit an application for certification to the marketplace that uses the certificate then it will need to be uploaded again. When you submit your app for certification to the marketplace you will have an opportunity to select a certificate for it from the list of certificates that you have uploaded. Just select the certificate that you uploaded for these communications and you are set.
- How do you know if this works? Well, when you create the HttpNotificationChannel class instance on the Windows Phone client, you will get back a notification channel Uri that send your messages to. Look at that Uri – if you are not using an authenticated connection, then you will see "throttledthirdparty" in the path. However if you created your class instance correctly, the path will contain "unthrottledthirdparty"; in addition the protocol it shows will be HTTPS instead of HTTP. Now of course, to really make sure it works, after you get that Uri back you need to successfully send a message. If it arrives at your device okay then you know it worked.