Izin untuk menyajikan file sementara


8

Saya memiliki sistem (aplikasi berbasis web) yang menarik lampiran file dari sistem pihak ke-3 melalui SOAP. Ini pada gilirannya pada sistem kami dibuat sebagai file dalam direktori.

Ketika pengguna sistem (dikonfirmasi melalui ldap) membuat permintaan ke aplikasi saya untuk mengambil salah satu dari lampiran ini:

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.  

Pertama, apakah ini pendekatan yang baik?

Apakah ada cara yang lebih baik untuk menyajikan file yang tidak akan berada di server banyak setelah unduhan lampiran (cron job akan membersihkan direktori begitu sering)?

Kedua, apakah ada cara saya bisa melayani file melalui apache tanpa menyimpannya di root web?

Ketiga, bagaimana cara menegakkan izin pada file-file ini sehingga tidak sembarang pengguna dapat mengunduh sembarang lampiran?

Pengaturan kami:

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

EDIT: Kode untuk melayani lampiran jika ada yang penasaran.

    <?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']));   
}


?>

Ini mungkin milik StackOverflow
John Conde

Jawaban:


2

Pertama, apakah ini pendekatan yang baik?

Kedengarannya baik bagi saya. Pastikan Anda mengautentikasi pengguna sebelum melalui semua itu.

Apakah ada cara yang lebih baik untuk menyajikan file yang tidak akan berada di server banyak setelah unduhan lampiran (cron job akan membersihkan direktori begitu sering)?

Kedua, apakah ada cara saya bisa melayani file melalui apache tanpa menyimpannya di root web?

Letakkan file di luar webroot. Kemudian menggunakan PHP lulus file melalui skrip. Dengan begitu tidak ada yang bisa menautkan ke file secara langsung dan memotong kontrol Anda. (Secara alami pastikan skrip yang melakukan ini hanya setelah memverifikasi pengguna memiliki izin untuk mengambil file itu).

Contoh PHP:

<?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;
?>

Ketiga, bagaimana cara menegakkan izin pada file-file ini sehingga tidak sembarang pengguna dapat mengunduh sembarang lampiran?

Buat pengguna masuk untuk mengambil file mereka. Kemudian Anda dapat mengatur variabel sesi yang mengidentifikasi mereka sebagai diizinkan untuk diunduh. Pastikan skrip Anda mengautentikasi mereka di setiap halaman proses ini.


Ini penjelasan yang bagus! Terima kasih. Berdasarkan saran Anda, akan lebih baik untuk menyimpan file-file ini di luar webroot dengan cara itu saya tidak perlu khawatir tentang tautan langsung / akses ke file dan hanya menyajikannya berdasarkan halaman php dengan logika yang mirip dengan di atas untuk memverifikasi otentikasi pengguna sebelum melayani file. Cheers
Chris

@ John Conde Saya melihat tipe konten tertentu sebagai "application / octet-stream" jadi ini akan bekerja dengan semua tipe file? Ini tidak berfungsi, juga tidak menentukan jenis mime konten. Misalnya saya punya pdf duduk di sana yang bisa saya tarik dan tahu adalah pdf yang baik tetapi ketika saya sajikan melalui mode yang Anda sajikan, saya menerima "Jenis file dokumen teks biasa (teks / polos) tidak didukung".
Chris

Saya percaya begitu. Jika tidak, yang perlu Anda lakukan adalah mengubah bagian itu ke tipe mime yang tepat. Tapi saya cukup yakin itu akan bekerja untuk semua jenis file.
John Conde

Untuk beberapa alasan, saya dapat melakukan upload / filename.pdf tetapi skrip php tidak dapat menayangkan file menggunakan aplikasi / octet-stream atau application / pdf untuk kasus khusus ini.
Chris

Kesalahan apa yang Anda dapatkan? Verifikasi bahwa skrip dapat menemukan file karena jalurnya mungkin salah di suatu tempat.
John Conde
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.