提供临时文件的权限


8

我有一个系统(基于Web的应用程序),可通过SOAP从第3方系统中提取文件附件。这些反过来又在我们的系统上创建为目录中的文件。

当系统用户(通过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提供文件而不将其存储在Web根目录中?

第三,如何对这些文件强制执行权限,以使不仅任何用户都不能下载任何附件?

我们的设置:

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


?>

这可能属于StackOverflow
John Conde

Answers:


2

首先,这是一个好方法吗?

对我来说还不错。只需确保对用户进行身份验证,然后再进行所有操作即可。

有没有更好的方法来处理附件下载后不会驻留在服务器上太多的文件(cron作业会经常清理目录)?

其次,有没有一种方法可以通过apache提供文件而不将其存储在Web根目录中?

将文件放在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;
?>

第三,如何对这些文件强制执行权限,以使不仅任何用户都不能下载任何附件?

使用户登录以检索其文件。然后,您可以设置一个会话变量,将其标识为允许下载。确保您的脚本在此过程的每个页面上对它们进行身份验证。


这是一个很好的解释!谢谢。根据您的建议,最好将这些文件存储在webroot之外,这样我就不必担心直接链接/访问文件,而只需基于php页面提供它们,并使用与上述类似的逻辑即可验证在提供文件之前对用户进行身份验证。干杯
克里斯,2010年

@John Conde我注意到特定于“应用程序/八位字节流”的内容类型,因此它适用于任何文件类型吗?这不起作用,也不指定内容mime-type。例如,我坐在那里有一个pdf文件,可以拉出,并且知道它是一个很好的pdf文件,但是当我通过您提出的方式提供该文件时,会收到“不支持文件类型的纯文本文档(文本/纯文本)”。
克里斯,2010年

我相信是这样。如果不是,那么您只需要将该部分更改为适当的mime类型即可。但是我很确定这对任何文件类型都适用。
约翰·孔德

由于某种原因,我可以转到uploads / filename.pdf,但是对于这种特定情况,php脚本无法使用application / octet-stream或application / pdf来提供文件。
克里斯,2010年

你得到什么错误?验证脚本可以找到该文件,因为该路径在某处可能不正确。
约翰·孔德
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.