一時ファイルを提供するための権限


8

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を介してファイルを提供できる方法はありますか?

3番目に、これらのファイルにアクセス許可を適用して、ユーザーだけで添付ファイルをダウンロードできないようにする方法を教えてください。

私たちのセットアップ:

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

回答:


2

まず、これは良いアプローチですか?

私には元気に聞こえます。そのすべてを実行する前に、ユーザーを認証していることを確認してください。

添付ファイルのダウンロード後にサーバーに常駐しないファイルを提供するためのより良い方法はありますか(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;
?>

3番目に、これらのファイルにアクセス許可を適用して、ユーザーだけで添付ファイルをダウンロードできないようにする方法を教えてください。

ユーザーにログインしてファイルを取得します。次に、ダウンロードが許可されていることを示すセッション変数を設定できます。スクリプトがこのプロセスのすべてのページでそれらを認証することを確認してください。


これは素晴らしい説明です!ありがとう。あなたの提案に基づいて、私はファイルへの直接リンク/アクセスを心配する必要がなく、上記と同様のロジックを持つPHPページに基づいてそれらを提供するだけであるので、これらのファイルをウェブルートの外に保存する方が良いでしょうファイルを提供する前のユーザーの認証。乾杯
クリス

@John Conde「アプリケーション/オクテットストリーム」として特定のコンテンツタイプに気づいたので、これはどのファイルタイプでも機能しますか?これは機能せず、コンテンツのMIMEタイプを指定することもできません。たとえば、私はそこに座って私がプルできるPDFがあり、優れたPDFであることを知っていますが、あなたが提示する方法でそれを提供すると、「ファイル形式のプレーンテキストドキュメント(テキスト/プレーン)はサポートされていません」と表示されます。
クリス

私はそう信じています。そうでない場合は、その部分を適切なMIMEタイプに変更するだけです。しかし、私はそれがどんなファイルタイプでもうまくいくと確信しています。
John Conde

何らかの理由で、uploads / filename.pdfに移動できますが、この特定のケースでは、phpスクリプトはapplication / octet-streamまたはapplication / pdfを使用してファイルを提供できません。
Chrisが

どのようなエラーが発生しますか?パスがどこかで正しくない可能性があるため、スクリプトがファイルを見つけられることを確認してください。
ジョンコンデ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.