it-swarm.asia

أذونات لخدمة الملفات المؤقتة

لدي نظام (تطبيق قائم على الويب) يسحب مرفقات الملفات من نظام جهة خارجية عبر SOAP. هذه بدورها على نظامنا خلق كملفات في الدليل.

عندما يقوم أحد مستخدمي النظام (مصادق عليه من خلال ldap) بتقديم طلب إلى طلبي لاسترداد أحد هذه المرفقات:

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.  

أولاً ، هل هذا مقاربة جيدة؟

هل هناك طريقة أفضل لخدمة الملفات التي لن تتواجد على الخادم بعد تنزيل المرفقات (ستقوم وظيفة cron بتنظيف الدليل في كثير من الأحيان)؟

ثانياً ، هل هناك طريقة يمكنني من خلالها تقديم الملفات من خلال Apache دون تخزينها في جذر الويب؟

ثالثًا ، كيف يمكنني فرض أذونات على هذه الملفات حتى لا يتمكن أي مستخدم من تنزيل أي مرفق فقط؟

الإعداد لدينا:

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

تحرير: رمز لخدمة المرفق في حالة أي شخص لديه فضول.

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


?>
8
Chris

أولاً ، هل هذا مقاربة جيدة؟

يبدو جيدا بالنسبة لي. فقط تأكد من مصادقة المستخدم قبل المرور بكل ذلك.

هل هناك طريقة أفضل لخدمة الملفات التي لن تتواجد على الخادم بعد تنزيل المرفقات (ستقوم وظيفة cron بتنظيف الدليل في كثير من الأحيان)؟

ثانياً ، هل هناك طريقة يمكنني من خلالها تقديم الملفات من خلال Apache دون تخزينها في جذر الويب؟

ضع الملفات خارج webroot. ثم استخدام PHP تمرير الملف من خلال برنامج نصي. وبهذه الطريقة ، لا يمكن لأي شخص الارتباط بالملف مباشرةً وتجاوز عناصر التحكم الخاصة بك. (تأكد من أن البرنامج النصي الذي يقوم بذلك فقط بعد التحقق من المستخدم لديه إذن لاسترداد هذا الملف).

عينة 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;
?>

ثالثًا ، كيف يمكنني فرض أذونات على هذه الملفات حتى لا يتمكن أي مستخدم من تنزيل أي مرفق فقط؟

اجعل المستخدمين يقومون بتسجيل الدخول لاسترداد ملفاتهم. بعد ذلك ، يمكنك تعيين متغير جلسة يعرّفهم على أنه مسموح لهم بتنزيله. تأكد من قيام البرامج النصية الخاصة بك بتوثيقها في كل صفحة من هذه العملية.

2
John Conde