質問
asp.netのメディアを保護する良い習慣を知っている人はいますか?
特定の画像/動画を表示する許可を必要とするさまざまなメディアをホストする必要があります。つまり、特定のユーザーはメディアファイルを表示する権限を持っている場合と持っていない場合があり、この事実はその場で変更される場合があります。
アクセスできるメディアファイルをダウンロードできるかどうかは気にしません。アクセスしてはいけないアイテムを認識させたくないだけです。
すでにURLの難読化を検討しました-これは非常に不自然なようです。
フォーム認証されたユーザーがいます(これを変更するつもりはありません)。
メディアファイルのフォルダー構造をアクセス許可とは無関係に保ちたい。
解決
すべてのメディアにアクセスする必要があるHttpHandlerを構築します。次に、ファイルを取得してユーザーに送信する前に、必要な検証を実行できます。すべてのメディアをメインのwwwrootパスの外側に置くか、権限を使用してそのフォルダーへのアクセスを拒否します。
このトピックの詳細はこちら:
他のヒント
このようなxmlファイルを使用して、ファイルにアクセスできるユーザー/グループを設定します
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root[
<!ELEMENT file ANY>
<!ATTLIST file name ID #REQUIRED>
]>
<root>
<file name="file.doc" users="155,321" groups="grp5" />
<file name="file2.doc" users="321" groups="" />
</root>
ファイルはhttpルートの上に保存されるため、URLでアクセスできません。
ユーザーがGetFile.aspx?file = file.docにアクセスしようとすると、XMLをロードし、次の行を取得します
XmlNode xnFile= XML.GetElementById(wantedFile);
、次に関数を呼び出します
HasAccess(Context.User, xnFile);
ユーザーがログインしているかどうかを確認し、アクセス許可を比較します。このユーザーがファイルを保持しても問題ない場合は、ディスクからファイルを読み取り、
FileInfo thisFile = new FileInfo(secretLocation + wantedFile);
Response.Clear();
Response.Buffer = false;
Response.BufferOutput = false;
Response.ClearContent();
Response.ClearHeaders();
Response.AddHeader("Content-Length", thisFile.Length.ToString());
Response.AddHeader("Content-disposition", "filename=" + thisFile.Name);
Response.ContentType = "application/none";
Response.WriteFile(secretLocation + wantedFile);
Response.Close();
Response.End();
Response.ClearContent();
Response.ClearHeaders();
実際には、1,000以上のファイルがあり、おそらくクラッシュまたは同時使用が原因でXMLが5年で2回破損したため、データベースにファイルデータを書き込むことを考えています。
Spikolynn回答のコメントから
私は困惑しています-これは難読化とどう違うのですか?認証されたユーザーは、認証されているが許可されていない別のユーザーと画像を共有できますか?
メディアの不正な共有を防止しようとしていると思います。
これは、多くの企業(Microsoft、Apple、IBMなど)が解決するために相当な金額を投入したものです。 ソリューションはDRM でしたが、失敗のため、現在削除しています。
だから、私の答えは、ユーザーがそれを避けるためにいくらか努力することをいとわないなら共有を防ぐことはできないということです。
Spikolynn または Lusid が回答で説明するように、いくつかのテクニックを適用することで、正直な人を正直に保つことができます。
各ユーザーがアクセスできるファイルを保持するテーブルを提案します:
UserID int
FileID varchar
次に、ファイルのテーブル:
FileID UniqueIdentifier
FileType char(4) <- so you know which extension to use.
etc...
ハードドライブで、ファイルにFileID(UniqueIdentifier)およびFileType(拡張子、たとえば.jpg)という名前を付けます。許可テーブルのfileIDは、他のテーブルで生成されたUniqueIdentifierを保持します。
これは、ユーザーが他のファイルの名前を推測できないことを比較的安全に知っているURL経由で渡すことができます。
更新:ちなみに、これはHttpHandlerの記述やファイル許可の処理よりもはるかに簡単です。ただし、誰かが別のファイル名を推測する可能性はわずかですが、あるユーザーが別のユーザーにファイルへのアクセスを許可する可能性があるため、機密性の高いセキュリティではありません。
brownpaperpackage.aspx?id = {guid}
media.aspxのLoadイベントで、ユーザーが認証されていることを確認し、ユーザーがメディアを表示する権利を持っていることを確認します。 Spikolynn が示すように。
なぜこのようにするのですか?コーディングが簡単で、ASP.NETおよびIISの認証サービスのすべての利点が得られ、そこからメディアを要求しているユーザーを見つけることができます。そのユーザーをメディアオブジェクトのアクセスリストにマップするのは簡単です。また、ページにはリクエストオブジェクトがあります。また、メディアの名前を非表示にしているため、URLから何が起こっているのかわかりません。
どのようにして人々があなたのメディアに直接アクセスしないようにしますか?メディアファイルをIIS仮想ディレクトリに保存することはできません。存在する場合は、直接ダウンロードできる可能性があります。それらをバイト配列(blob)としてデータベースに保存するか、Web仮想ディレクトリの外部のディスクに保存できます。ユーザーは、ASP.NETを介してファイルにアクセスする必要があります
どのユーザーがどのメディアにアクセスできるかをどのように追跡しますか? asp.netメンバーシップを通じてユーザーを追跡します。つまり、各ユーザーはaspnet_usersテーブルにIDを持っています。 idとファイル名(または実際のメディアを含むblob)を使用して、メディアのテーブルを作成します。次に、2つを接続する3番目のテーブルを作成するだけです。このテーブルには、ユーザーIDとメディアIDが含まれ、このユーザーがこのメディアを表示できることを示します。ユーザーID(asp.netメンバーシップから)およびメディアID(URLから)を使用するだけで、
select count(*) from UserMedia where UserId = @UserGuid and MediaId = @MediaIdFromUrl
およびカウントが<!> gtの場合; 0ユーザーはメディアを表示できます。
URLの使用例:
<asp:image
runat="server"
ImageUrl="brownpaperpackage.aspx?id=53a2ea4(snip)76ca8b" />