Christine
Christine

Reputation: 629

Secure pdf files and Xamarin Forms

I have a forms app which requires authentication. One of my pages is a webview, and I use cookies to send the authentication status through the webview to the server. On the webpage is a link to a .pdf file which also requires authentication. When this link is tapped I grab the url and attempt to open it using Device.OpenUri, but the authentication fails. Is there a way to send the authentication cookies along with the url to OpenUri, or another way to make the device's browser aware that the user is authenticated? Or is there another way to download the pdf file in the webview?

Upvotes: 2

Views: 800

Answers (1)

Adam
Adam

Reputation: 16199

Because Device.OpenUri, will just open another app with the url, there is no way to pass authentication through. What you need to do is download the PDF to local storage, then open the PDF from your local storage. You will need to place the file in shared storage on your mobile device to allow the other application to have access to it.

If that is a security risk, you will need to add an internal PDF Viewer to your app, so you can view the PDF in your app internally.

Now, if you want to download the PDF, you will need to use HttpClient. In iOS and UWP, the HttpClient and WebView share the same cookie container, which means if you authenticated on the WebView, it will already be authenticated in the HttpClient. For Android, you need to copy the authentication cookies across.

First establish a cookie container you can read.

CookieContainer _cookieContainer = new CookieContainer();
System.Net.Http.HttpClient _client = new System.Net.Http.HttpClient(new HttpClientHandler() { CookieContainer = _cookieContainer });

Then depending upon which way you want to copy, you can do

private void CopyCookies(HttpResponseMessage result, Uri uri)
{
    foreach (var header in result.Headers)
        if (header.Key.ToLower() == "set-cookie")
            foreach (var value in header.Value)
                 _cookieManager.SetCookie($"{uri.Scheme}://{uri.Host}", value);

    foreach (var cookie in GetAllCookies(_cookieContainer))
        _cookieManager.SetCookie(cookie.Domain, cookie.ToString());
}

or

public void ReverseCopyCookies(Uri uri)
{
    var cookie = _cookieManager.GetCookie($"{uri.Scheme}://{uri.Host}");

    if (!string.IsNullOrEmpty(cookie))
        _cookieContainer.SetCookies(new Uri($"{uri.Scheme}://{uri.Host}"), cookie);
}

I go into more detail in Cookie Sharing with WebView and the Http Client.

Upvotes: 4

Related Questions