web-dev-qa-db-ja.com

一時ファイルを提供するためのアクセス許可

SOAP経由でサードパーティシステムから添付ファイルをプルするシステム(Webベースのアプリケーション)があります。これらは、ディレクトリ内のファイルとして作成されたシステム上に順番にあります。

システムのユーザー(ldapを介して認証された)が、これらの添付ファイルの1つを取得するためにアプリケーションに要求を行うと:

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ジョブは、ディレクトリを時々クリーンアップします)?

次に、ファイルをWebルートに保存せずに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ジョブは、ディレクトリを時々クリーンアップします)?

次に、ファイルをWebルートに保存せずに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