Autorizzazioni per la pubblicazione di file temporanei


8

Ho un sistema (applicazione web based) che estrae i file allegati da un sistema di terze parti tramite SOAP. Questi sono a loro volta sul nostro sistema creato come file in una directory.

Quando un utente del sistema (autenticato tramite ldap) invia una richiesta alla mia applicazione per recuperare uno di questi allegati:

1. I request it via soap
2. Process the response to build the file on our system
3. Redirect user to the location so they can download the file.  

Prima di tutto, è un buon approccio?

C'è un modo migliore per servire i file che non risiederanno sul server molto dopo il download dell'allegato (cron job pulirà la directory ogni tanto)?

In secondo luogo, c'è un modo in cui posso servire i file tramite apache senza memorizzarli nella web root?

In terzo luogo, come posso applicare le autorizzazioni per questi file in modo che non tutti gli utenti possano scaricare qualsiasi allegato?

La nostra configurazione:

linux
apache
php - soap libraries for communication 
seperate LDAP for authentication
3rd party soap server (where attachments come from) 

EDIT: il codice per servire l'allegato nel caso qualcuno fosse curioso.

    <?php 

ini_set('display_errors',1);
error_reporting(E_ALL|E_STRICT);

//require global definitions 
require_once("includes/globals.php"); 
//validate the user before continuing 
isValidUser(); 
$subTitle = "Attachment";   
$attachmentPath = "/var/www/html/DEVELOPMENT/serviceNow/selfService/uploads/";
if(isset($_GET['id']) and !empty($_GET['id'])){
    //first lookup attachment meta information 
    $a = new Attachment(); 
    $attachment = $a->get($_GET['id']); 
    //filename will be original file name with user name.n prepended 
    $fileName = $attachmentPath.$_SESSION['nameN'].'-'.$attachment->file_name; 
    //instantiate new attachmentDownload and query for attachment chunks 
    $a = new AttachmentDownload(); 
    $chunks= $a->getRecords(array('sys_attachment'=>$_GET['id'], '__order_by'=>'position')); 


    $fh = fopen($fileName.'.gz','w');                                                      
    // read and base64 encode file contents 
    foreach($chunks as $chunk){
            fwrite($fh, base64_decode($chunk->data));   
    }
    fclose($fh);

    //open up filename for writing 
    $fh = fopen($fileName,'w');     
    //open up filename.gz for extraction                                
    $zd = gzopen($fileName.'.gz', "r");
    //iterate over file and write contents 
    while (!feof($zd)) {
            fwrite($fh, gzread($zd, 60*57));    
    }
    fclose($fh); 
    gzclose($zd);
    unlink($fileName.'.gz'); 
    $info = pathinfo($fileName); 

    header('Content-Description: File Transfer');
    header('Content-Type: '.Mimetypes::get($info['extension']));
    header('Content-Disposition: attachment; filename=' . basename($fileName));
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    header('Pragma: public');
    header('Content-Length: ' . filesize($fileName));
    ob_clean();
    flush();
    readfile($fileName);
    exit();
}else{
    header("location: ".$links['status']."?".urlencode("item=incident&action=view&status=-1&place=".$links['home']));   
}


?>

Questo probabilmente appartiene a StackOverflow
John Conde

Risposte:


2

Prima di tutto, è un buon approccio?

Suona bene per me. Assicurati di autenticare l'utente prima di passare a tutto ciò.

C'è un modo migliore per servire i file che non risiederanno sul server molto dopo il download dell'allegato (cron job pulirà la directory ogni tanto)?

In secondo luogo, c'è un modo in cui posso servire i file tramite apache senza memorizzarli nella web root?

Metti i file fuori dal webroot. Quindi usando PHP passa il file attraverso uno script. In questo modo nessuno può collegarsi direttamente al file e bypassare i controlli. (Assicurati naturalmente che lo script che lo fa solo dopo aver verificato che l'utente abbia il permesso di recuperare quel file).

PHP di esempio:

<?php
    if (!isset($_SESSION['authenticated']))
    {
        exit;
    }
    $file = '/path/to/file/outside/www/secret.pdf';

    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename=' . basename($file));
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    header('Pragma: public');
    header('Content-Length: ' . filesize($file));
    ob_clean();
    flush();
    readfile($file);
    exit;
?>

In terzo luogo, come posso applicare le autorizzazioni per questi file in modo che non tutti gli utenti possano scaricare qualsiasi allegato?

Fai accedere gli utenti per recuperare i loro file. Quindi è possibile impostare una variabile di sessione identificandoli come autorizzati a scaricare. Assicurati che i tuoi script li autenticano su ogni pagina di questo processo.


Questa è un'ottima spiegazione! Grazie. Sulla base del tuo suggerimento, sarebbe meglio archiviare questi file al di fuori del webroot in questo modo, non devo preoccuparmi del collegamento diretto / accesso ai file e semplicemente servirli in base a una pagina php con logica simile a quella sopra per verificare il autenticazione dell'utente prima di pubblicare il file. Saluti
Chris,

@John Conde Ho notato il tipo di contenuto specifico come "application / octet-stream", quindi funzionerà con qualsiasi tipo di file? Questo non funziona, né specifica il tipo mime del contenuto. Ad esempio ho un pdf seduto lì che posso estrarre e so che è un buon pdf ma quando lo offro tramite la moda che presenti, ricevo "Il tipo di documento documento di testo semplice (testo / semplice) non è supportato".
Chris,

Credo di sì. In caso contrario, tutto ciò che devi fare è cambiare quella parte con il tipo MIME corretto. Ma sono abbastanza sicuro che funzionerà con qualsiasi tipo di file.
John Conde

Per qualche ragione, posso andare su uploads / nomefile.pdf ma lo script php non può servire il file usando sia application / octet-stream che application / pdf per questo caso specifico.
Chris,

Che errore ricevi? Verifica che lo script sia in grado di trovare il file poiché il percorso potrebbe non essere corretto da qualche parte.
John Conde
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.