Unprotected PDF and Word files asking for password on load?

Hi there, I'm loading documents from our web API and displaying them using the SfPdfViewer by binding the InputFileStream DependencyProperty on my VM to a MemoryStream of the document download request content converted to a byte array.

The document is downloaded correctly and I have verified that doing a direct download on a mobile device, in emulator, and as well as in a PC web browser is able to load the document without entering any password; however, when I try to load the document into the SfPdfViewer, I'm greeted with the password popup. To make matters worse, the password box doesn't seem to accept numerals (0-9) from the soft keyboard, so I can't even try the logged in user's actual password.

Any help is greatly appreciated. I'm using Xamarin.Forms version 4.8.0.1687 and SyncFusion.Xamarin version 18.3.0.51. For Android I am targeting API level 29 and minimum level 21, testing on a Pixel 3 XL Pie 9.0 (API 28) virtual device. I have a Mac available for iOS testing, as well as a physical Android device I can also test on.

10 Replies

AG Aribalakrishnan Govindasamy Syncfusion Team November 25, 2020 03:07 PM UTC

Hi Andrew, 

Greetings from Syncfusion support, 

We were unable to reproduce the issue, “PDFViewer asks for password for loading a unprotected PDF document”, its working as expected.  

 Please find the sample which we have used to reproduce the issue,  


Kindly share the following details to analyse more on this issue and assist you with the better solution    
     1.Simple sample/ Modify the above sample to reproduce the issue 
     2.PDF document (URL link) 
     3.Replication procedure to reproduce the issue 

Regards, 
Aribalakrishnan G. 



AH Andrew Hoke November 25, 2020 11:13 PM UTC

Hi Aribalakrishnan, I've downloaded your sample app and tried two things:
1. I embedded the PDF download as a resource and loaded it directly from within the application with Assembly.GetManifestResourceStream(). I don't get a password popup with this method.
2. I go back to downloading the file from the API, I am once again greeted with a password prompt, even when using the entire save and load process in the sample app.

I am attaching the raw document data as it was received from my API. The contents are a simple, one-page sample resume. Attempting to load this data via a Stream to an SfPdfViewer control results in a password prompt using both my app and the sample app provided.

Attachment: Sample_resume_39adeeee.zip

Update: I have also tried exporting a Word document as a PDF with the option to encrypt and add a password. I then tried loading this document in the PDF Viewer, entered the password I used, and I still got the invalid password error. I can only reproduce this issue with the SyncFusion PDF Viewer control, and nothing else I try is causing the same issue to occur.

Update 2: I have even resorted to attempting to open a .txt file, which could not possibly bear any encryption or password protection, and even that has prompted me for the password. I'm out of ideas.


SP Satheesh Palanisamy Syncfusion Team November 26, 2020 06:30 PM UTC

Hi Andrew,  
 
We were unable to reproduce the issues that you have reported in the previous update. 
 
Please find the sample which we have used to reproduce the issue,   
 
 
Kindly share the following details to analyse more on this issue and assist you with the better solution     
     1.Simple sample/ Modify the above sample to reproduce the issue  
     2.PDF document (URL link)  
     3.Replication procedure to reproduce the issue. 
 
Regards,  
Satheesh Palanisamy. 



AH Andrew Hoke November 30, 2020 04:13 PM UTC

Hi Satheesh,

Can you confirm you were unable to reproduce the issue using the document I attached in my last reply? A sample project using LoadDocument with a password will not work because we have not added any passwords to our documents. Our repository stores the documents as uploaded, so no password protection is added. Therefore, I don't even know what password to attempt to unlock the documents.


AH Andrew Hoke November 30, 2020 06:20 PM UTC

I've done some more digging, including adding the SyncFusion Word to PDF conversion packages. When opening a Word document using the SF WordDocument API, I find that the document's one and only WSection has the ProtectForm property set to true. This is in fact not the case as the document I will attach here is not protected in any way! Since this property is set, the PDF conversion using DocIORenderer.ConvertToPDF(WordDocument) is resulting in the PdfDocument's security settings to show as "EncryptAllContents". I'm beyond stumped at this point and quite frustrated with what should be a very simple process. I've also attached a screenshot showing the document's protection settings reflecting no document protection of any sort. Any technical suggestions beyond "cannot reproduce, here's a sample project" would be most helpful as I'm spending precious time sorting this issue out.


Word Document showing "ProtectForm" property incorrectly set to true (I believe this is the official Word interop property equivalent):


PdfDocument showing EncryptAllContents set to true; I never specified this anywhere:


Word document protection pane showing no document protection settings being enforced:




AH Andrew Hoke November 30, 2020 09:03 PM UTC

I've done even more tinkering and have found a band-aid solution to the issues I've encountered. Using an intermediate PdfLoadedDocument constructed from the PDF data stream then saving the contents of the PdfLoadedDocument into a new stream and passing that to the SfPdfViewer, I am now able to load my documents. I wish this was simpler, but it is what it is until a more elegant solution presents itself.


AV Ashokkumar Viswanathan Syncfusion Team December 1, 2020 10:43 AM UTC

Hi Andrew, 
 
Thank you for your update, 
 
We have tried to load the PDF document which is converted using the provided Word document, its working as expected in our end.  
 
Please find the modified sample where we will be converting Word document to PDF and loading the PDF stream into PDFViewer control, 
 
Please refer the below screenshot, 
 
 
Based on your last update, we hope that using intermediate PdfLoadedDocument resolved the issue in your end. However kindly try the above-provided sample and confirm whether we have missed out anything while replicating the issue. 
 
Regards, 
Ashok Kumar Viswanathan. 



KI kingleroyg July 4, 2021 08:23 PM UTC

 @Andrew any chance you could share your solution ? the solution from support is horrible ( literally converting into Jpeg images then word document then pdf documents again)



AH Andrew Hoke replied to kingleroyg July 5, 2021 04:57 PM UTC

I ended up doing some really gross client-side conversion of the documents to get the password prompts to go away:


var docStream = new MemoryStream(response.RawBytes);
Stream outputStream = new MemoryStream();
switch (response.ContentType)
{
	case "application/pdf":
		PdfLoadedDocument pdfLoadedDocument = new PdfLoadedDocument(docStream);
		pdfLoadedDocument.Save(outputStream);
		break;
	case "text/plain":
		// We need to construct a temporary PDF document from plaintext
		PdfDocument tempDoc = new PdfDocument();
		var page = tempDoc.Pages.Add();
		var pageGfx = page.Graphics;
		PdfTextElement contents = new PdfTextElement(response.Content, new PdfStandardFont(PdfFontFamily.Helvetica, 12));
		contents.Draw(
			page,
			new RectangleF(0, 0, page.GetClientSize().Width, page.GetClientSize().Height),
			new PdfLayoutFormat { Layout = PdfLayoutType.Paginate, Break = PdfLayoutBreakType.FitPage });
		tempDoc.Save(outputStream);
		tempDoc.Close();
		break;
	case "application/msword":
	case "application/vnd.openxmlformats-officedocument.wordprocessingml.document":
		WordDocument wordDocument = new WordDocument(docStream, Syncfusion.DocIO.FormatType.Automatic);
		DocIORenderer render = new DocIORenderer();
		render.Settings.ChartRenderingOptions.ImageFormat = ExportImageFormat.Jpeg;
		
		PdfDocument pdfDocument = render.ConvertToPDF(wordDocument);
		render.Dispose();
		wordDocument.Dispose();
		MemoryStream tempStream = new MemoryStream();
		pdfDocument.Save(tempStream);
		PdfLoadedDocument pdfReloadedDocument = new PdfLoadedDocument(tempStream);
		pdfReloadedDocument.Save(outputStream);
		break;
	default:
		break;
}

Note: I am using RestSharp in my app. You can replace the assignment of "docStream" with the method of accessing the raw bytes of the document that is relev



KI kingleroyg replied to Andrew Hoke July 7, 2021 11:13 AM UTC

Thanks for the quick reply!!!!!!!!!!!!!!!!!!!!!!!!! :)

after spending a whole nighter on this I figured out that its our client api's that affect the bytes. I'm using refit and had the exact same password issue as you. I switched to HttpClient and some how it worked.


`        public MainPage()

        {

            InitializeComponent();

            LoadDocumentFromInternet();

        }


        public async Task LoadDocumentFromInternet()

        {

            pdfViewerControl.LoadDocument(await DownloadPdfStream("http://www.africau.edu/images/default/sample.pdf"));

        }


        private async Task<Stream> DownloadPdfStream(string URL)

        {

            HttpClient httpClient = new HttpClient();

            HttpResponseMessage response = await httpClient.GetAsync(URL);

            //Check whether redirection is needed

            if ((int)response.StatusCode == 302)

            {

                //The URL to redirect is in the header location of the response message

                HttpResponseMessage redirectedResponse = await httpClient.GetAsync(response.Headers.Location.AbsoluteUri);

                return await redirectedResponse.Content.ReadAsStreamAsync();

            }

            return await response.Content.ReadAsStreamAsync();

        }

`


Loader.
Up arrow icon