itext 在签名后锁定某些字段 - 一个字段正常但第二个字段签名导致错误?

问题描述 投票:0回答:1

所以我想检查 itext(版本 8)是否适合我的需要

我需要添加符号字段并基于它们以宏形式锁定一些其他字段,

所以我喜欢它:

            PdfWriter writer = new PdfWriter("AddSignFieldItext77.pdf");
            iText.Kernel.Pdf.PdfDocument pdf = new iText.Kernel.Pdf.PdfDocument(writer);

            var newPage = pdf.AddNewPage(new PageSize(PageSize.A4));
            PdfAcroForm form = PdfAcroForm.GetAcroForm(pdf, true);

            var formRectangle = new iText.Kernel.Geom.Rectangle(100, 800, 200, 20);
            var formFieldBuilder = new TextFormFieldBuilder(pdf, "TextFormField1");
            formFieldBuilder.SetPage(newPage);
    
            formFieldBuilder.SetWidgetRectangle(formRectangle);
            var formfield = formFieldBuilder.CreateText();
            form.AddField(formfield);

            var formRectangle2 = new iText.Kernel.Geom.Rectangle(100, 700, 200, 20);
            var formFieldBuilder2 = new TextFormFieldBuilder(pdf, "TextFormField2");
            formFieldBuilder2.SetPage(newPage);

            formFieldBuilder2.SetWidgetRectangle(formRectangle2);
            var formfield2 = formFieldBuilder2.CreateText();
            form.AddField(formfield2);

           
            var signatureRectangle1 = new iText.Kernel.Geom.Rectangle(36, 448, 200, 100);
            var signatureField1 = new SignatureFormFieldBuilder(pdf, "SignField1");
            signatureField1.SetPage(newPage);
            signatureField1.SetWidgetRectangle(signatureRectangle1);
            PdfSignatureFormField sig1 = signatureField1.CreateSignature();
            

            PdfSigFieldLock pdfSigFieldLock1 = new PdfSigFieldLock();          
            string[] fieldToLock1 = new string[] { "TextFormField1" };
            pdfSigFieldLock1.SetFieldLock(PdfSigFieldLock.LockAction.INCLUDE, fieldToLock1);         
            PdfDictionary dict = sig1.GetPdfObject();
            dict.Put(PdfName.Lock,pdfSigFieldLock1.GetPdfObject());
            form.AddField(sig1);


            var signatureRectangle2 = new iText.Kernel.Geom.Rectangle(36, 248, 200, 100);
            var signatureField2 = new SignatureFormFieldBuilder(pdf, "SignField2");
            signatureField2.SetPage(newPage);
            signatureField2.SetWidgetRectangle(signatureRectangle2);
            PdfSignatureFormField sig2 = signatureField2.CreateSignature();

            PdfSigFieldLock pdfSigFieldLock2 = new PdfSigFieldLock();         
            string[] fieldToLock2 = new string[] { "TextFormField2", };
            pdfSigFieldLock2.SetFieldLock(PdfSigFieldLock.LockAction.INCLUDE,fieldToLock2 );
            PdfDictionary dict2 = sig2.GetPdfObject();
            dict2.Put(PdfName.Lock, pdfSigFieldLock2.GetPdfObject());
            form.AddField(sig2);
            pdf.Close();

这几乎可以正常工作-像这样生成 pdf

我可以签署第一场。没事。已保存,已签名,

TextFormField1
已锁定。

然后如果我想在第二个字段上签名——我得到错误,如屏幕截图所示,函数参数值不正确?

如果我关闭并重新打开文档-我可以在这个

SignField2
上无误地登录 但我不想为了第二次签名而关闭并重新打开文档

请建议如何解决这个问题——我在这里遗漏了什么吗?有更好的方法吗?

致以诚挚的问候

c# pdf itext digital-signature acrofields
1个回答
2
投票

事实上,当您尝试在单个会话中对两个签名字段进行签名时,Adobe Acrobat(至少是我目前使用的版本 2023.001.20174)会遇到问题。

第一次检查时,PDF 中没有发现任何错误。因此,我使用 Adobe Acrobat 本身创建了一个类似的文件,并观察到 Adobe Acrobat 没有遇到同样的问题。然后我确定了差异并试图找出哪些差异是相关的。

事实证明,只有一个相关的区别:如果签名字段词典具有正确的 Type 条目,Adobe Acrobat 可以在单个会话中对两个 PDF 签名字段进行签名。另一方面,iText 默认不添加 Type 条目。

由于 Type 条目被指定为 optional 并且在签名字段字典的情况下只有一个允许的值,这显然可以被认为是 Adobe Acrobat 错误。

作为变通方法,您可以像这样使用 iText 显式添加类型:

...
PdfSigFieldLock pdfSigFieldLock1 = new PdfSigFieldLock();
string[] fieldToLock1 = new string[] { "TextFormField1" };
pdfSigFieldLock1.SetFieldLock(PdfSigFieldLock.LockAction.INCLUDE, fieldToLock1);
PdfDictionary dict = sig1.GetPdfObject();
dict.Put(PdfName.Type, PdfName.Annot); // <-----
dict.Put(PdfName.Lock, pdfSigFieldLock1.GetPdfObject());
form.AddField(sig1);
...
PdfSigFieldLock pdfSigFieldLock2 = new PdfSigFieldLock();
string[] fieldToLock2 = new string[] { "TextFormField2", };
pdfSigFieldLock2.SetFieldLock(PdfSigFieldLock.LockAction.INCLUDE, fieldToLock2);
PdfDictionary dict2 = sig2.GetPdfObject();
dict2.Put(PdfName.Type, PdfName.Annot); // <-----
dict2.Put(PdfName.Lock, pdfSigFieldLock2.GetPdfObject());
form.AddField(sig2);
...
© www.soinside.com 2019 - 2024. All rights reserved.