WinRT shared cookies between WebView and HttpClient

I recently worked on a project where we needed to make hybrid apps, consisting of native Universal Windows apps that displayed a responsive web application in the app through the WebView control. The web application contained some resources that needed to be routed to the device’s native browser to display certain types of content, but the problem there would be that the user’s session would be lost if the URL to the resource would just be opened in the native browser.

To circumvent this, we implemented the “nonce pattern“, which basically fetches an arbitrary number from the server using the user’s session, which can then be used to access the web resource securely, only once. To get the nonce value from the server, a custom HTTP request has to be made to a web service and to do this securely, the WebView’s session cookie would need to be re-used. This resulted in an interesting challenge: how does one share cookies between the WebView and HttpClient on WinRT?

Nonce-based authentication process

Using the portable System.Net.Http.HttpClient

As the app’s architecture held the back-end communication logic in a Portable Class Library, I was obviously using the portable HttpClient, available through the Microsoft HTTP Client Libraries NuGet. As I was calling things from a WinRT app (Windows/Windows Phone), I needed to extract the cookies from the WebView and send them on to the HttpClient in the portable class library. Luckily, the cookies used in the WebView are stored in the app’s HttpBaseProtocolFilter, so extracting them is fairly straightforward:

However, the GetCookies method of the HttpCookieManager class returns an HttpCookieCollection, which is a collection of Windows.Web.Http.HttpCookie. If we take a look at the code to use the cookie from the portable HttpClient, however, we’ll encounter a mismatch in cookie classes:

As you may notice, I’m creating a CookieContainer and adding the cookie (or several, if that’s needed) to it. Then I define an HttpClientHandler to hand the CookieContainer to the portable HttpClient. However, the cookies that are added to the CookieContainer need to be of type System.Net.Cookie and not Windows.Web.Http.HttpCookie as we received from the HttpCookieCollection in the HttpCookieManager. Some custom conversion code is thus necessary:

Using this approach, we’re all set and can use the cookies in the portable HttpClient.

Portable HttpClient caveat

This post wouldn’t be complete without stating the one caveat there is when using this approach: certain cookies can be marked as HttpOnly by the server, which is a flag created to “mitigate the risk of client side script accessing the protected cookie”. Basically what this means is that an HttpOnly cookie cannot be accessed by client side script, which includes our C# code to fetch the cookies through the CookieManager. The session ID cookie is usually an HttpOnly cookie, so that’s a cookie you won’t be able to pass through to the portable HttpClient using the above method and we needed that to fetch the nonce value from our back-end securely.

Using the Windows.Web.Http.HttpClient

To get around the caveat I mentioned and frankly if your architecture does not use Portable Class Libraries, but Shared Projects or just is a single project on WinRT, you should use Windows.Web.Http.HttpClient instead of the portable HttpClient. Using this approach, the cookies are automatically shared through the app’s context between the HttpClient and the WebView, including the HttpOnly cookies. Literally the only thing you have to do is create an instance of HttpClient and start your GET/POST and the session is automatically carried over from the WebView.

As usual, if you have questions, comments or feedback, let me know below or through Twitter!

Pin It

3 thoughts on “WinRT shared cookies between WebView and HttpClient

  1. Pingback: WinRT shared cookies between WebView and HttpClient - Rajen's Technical Tidbits - Site Home - MSDN Blogs

  2. Pingback: WinRT shared cookies between WebView and HttpClient

  3. Pingback: Sharing Http sessions between WebView requests and HttpClient on Windows Phone | Kloud Blog

Leave a Reply

Your email address will not be published. Required fields are marked *