有谁知道保护 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 root 之上,因此无法通过 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();
实际上,现在我有一千多个文件,我想将文件数据写入数据库,因为 XML 在 5 年内损坏了两次,可能是由于崩溃或同时使用。
根据您在 Spikolynn 答案中的评论
我很困惑——这与混淆有什么不同?经过身份验证的用户是否能够与另一个经过身份验证但未经授权的用户共享图像(他们被授权)?
我猜你试图阻止未经授权的媒体共享。
这是很多公司(微软、苹果、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)为您的媒体创建一个表。然后,您只需要创建连接两者的第三个表。该表将包含一个用户 ID 和一个媒体 ID,表示该用户可以查看该媒体。使用用户 ID(来自 asp.net Membership)和媒体 ID(来自 URL),您只需要
select count(*) from UserMedia where UserId = @UserGuid and MediaId = @MediaIdFromUrl
如果计数 > 0,则用户可以查看媒体。
如何使用 URL 的示例:
<asp:image
runat="server"
ImageUrl="brownpaperpackage.aspx?id=53a2ea4(snip)76ca8b" />