2012-10-25 22 views
5

Im davvero in difficoltà con la documentazione per PDFBox. Per informazioni così popolari, la libreria sembra essere un po 'sottile (per me!).Protezione del PDF con PDFBox

In ogni caso il problema che mi riguarda riguarda la protezione del PDF. Al momento tutto ciò che voglio è controllare i permessi di accesso degli utenti. nello specifico voglio impedire all'utente di essere in grado di modificare il PDF.

Se ometto il codice di accesso, tutto funziona perfettamente. Sto leggendo in un PDF da una risorsa esterna. Sto quindi leggendo e popolando i campi, aggiungendo alcune immagini prima di salvare il nuovo PDF. Tutto funziona perfettamente.

Il problema nasce quando aggiungo il seguente codice per gestire l'accesso:

/* Secure the PDF so that it cannot be edited */ 
try { 
    String ownerPassword = "DSTE$gewRges43"; 
    String userPassword = ""; 

    AccessPermission ap = new AccessPermission(); 
    ap.setCanModify(false); 

    StandardProtectionPolicy spp = new StandardProtectionPolicy(ownerPassword, userPassword, ap); 
    pdf.protect(spp); 
} catch (BadSecurityHandlerException ex) { 
    Logger.getLogger(PDFManager.class.getName()).log(Level.SEVERE, null, ex); 
} 

Quando aggiungo questo codice, tutto il testo e le immagini sono a strisce dal pdf in uscita. I campi sono ancora presenti nel documento ma sono tutti vuoti e tutto il testo e le immagini che contengono parte del PDF originale e che sono stati aggiunti dinamicamente nel codice sono scomparsi.

AGGIORNAMENTO: Ok, come meglio posso dire che il problema deriva da un bug relativo ai campi del modulo. Ho intenzione di provare un approccio diverso senza i campi del modulo e vedere cosa dà.

+0

Sto riscontrando lo stesso problema con i PDF casuali che restituiscono spazi vuoti. Qualche idea? – NightWolf

+0

Non sono mai arrivato in fondo a questo problema. Alla fine ho dovuto usare una libreria diversa! – tarka

+0

Grazie. Ho trovato una soluzione per te. – NightWolf

risposta

7

Ho trovato la soluzione a questo problema. Sembrerebbe che se il PDF proviene da una fonte esterna, a volte il PDF è protetto o crittografato.

Se si ottiene un risultato vuoto quando si carica un documento PDF da una fonte esterna e si aggiungono protezioni, si sta probabilmente lavorando con un documento crittografato. Ho un sistema di elaborazione dei flussi che funziona su documenti PDF. Quindi il seguente codice funziona per me. Se stai semplicemente lavorando con gli input PDF, potresti integrare il codice seguente con il tuo flusso.

public InputStream convertDocument(InputStream dataStream) throws Exception { 
    // just acts as a pass through since already in pdf format 
    PipedOutputStream os = new PipedOutputStream(); 
    PipedInputStream is = new PipedInputStream(os); 

    System.setProperty("org.apache.pdfbox.baseParser.pushBackSize", "2024768"); //for large files 

    PDDocument doc = PDDocument.load(dataStream, true); 

    if (doc.isEncrypted()) { //remove the security before adding protections 
     doc.decrypt(""); 
     doc.setAllSecurityToBeRemoved(true); 
    } 
    doc.save(os); 
    doc.close(); 
    dataStream.close(); 
    os.close(); 
    return is; 
} 

Ora prendi InputStream restituito e utilizzalo per l'applicazione di sicurezza;

PipedOutputStream os = new PipedOutputStream(); 
    PipedInputStream is = new PipedInputStream(os); 

    System.setProperty("org.apache.pdfbox.baseParser.pushBackSize", "2024768"); 
    InputStream dataStream = secureData.data(); 

    PDDocument doc = PDDocument.load(dataStream, true); 
    AccessPermission ap = new AccessPermission(); 
    //add what ever perms you need blah blah... 
    ap.setCanModify(false); 
    ap.setCanExtractContent(false); 
    ap.setCanPrint(false); 
    ap.setCanPrintDegraded(false); 
    ap.setReadOnly(); 

    StandardProtectionPolicy spp = new StandardProtectionPolicy(UUID.randomUUID().toString(), "", ap); 

    doc.protect(spp); 

    doc.save(os); 
    doc.close(); 
    dataStream.close(); 
    os.close(); 

Ora questo dovrebbe restituire un documento corretto senza output vuoto!

Il trucco è di rimuovere prima la crittografia!

+0

L'uso di 'PipedOutputStream' e' PipedInputStream' nel codice a thread singolo è un po 'bizzarro. – mkl

+0

Siamo spiacenti. In questo esempio il ref di pipedinputstream viene effettivamente passato ad un altro thread (questo codice vive in attori akka bloccati). Ho omesso le mandate nel codice sopra. – NightWolf

Problemi correlati