有谁知道为asp.net保护媒体的良好做法?
我需要托管各种需要获得查看特定图片/视频权限的媒体。即特定用户可能有也可能没有查看媒体文件的权限 - 这个事实可能会动态更改。
我不在乎他们是否可以下载他们有权访问的媒体文件,我只是不希望他们甚至知道他们不应该访问的项目。
我已经考虑过网址混淆 - 这对我来说似乎很蹩脚。
我已经过身份验证的用户(我不想改变这个)。
我希望将媒体文件文件夹结构与权限无关。
答案 0 :(得分:11)
构建一个必须通过访问所有媒体的HttpHandler。然后,在检索文件并将其发送给用户之前,您可以执行任何您想要的验证。将所有媒体保留在主wwwroot路径之外,或使用权限拒绝访问该文件夹。
此处有关此主题的更多信息:
答案 1 :(得分:2)
我使用这样的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年内损坏了两次,可能是由于崩溃或同时使用。
答案 2 :(得分:1)
来自您在Spikolynn答案中的评论
我很困惑 - 这与混淆有什么不同?经过身份验证的用户是否能够与另一个经过身份验证但未经授权的用户共享图像(他们被授权)?
我猜您尝试阻止未经授权共享媒体。
很多公司(微软,苹果,IBM等)已投入大量资金解决这个问题。 解决方案是DRM ,现在他们正在将其删除,因为失败了。
所以,我的回答是,如果用户愿意付出一些努力来避免共享,无法阻止共享。
你可以通过在答案中使用 Spikolynn 或 Lusid 解释一些技巧来保持诚实的人诚实。
答案 3 :(得分:0)
我建议一个表格,其中包含每个用户都可以访问的文件:
UserID int
FileID varchar
然后是您的文件表:
FileID UniqueIdentifier
FileType char(4) <- so you know which extension to use.
etc...
在硬盘驱动器上,将文件命名为FileID(UniqueIdentifier)和FileType(扩展名,例如.jpg)。权限表中的fileID将保存在另一个表中生成的UniqueIdentifier。
您可以通过网址传递此信息,相对安全,用户将无法猜出任何其他文件的名称。
更新:顺便说一下,这比编写HttpHandler或处理文件权限更简单 。然而,虽然有人猜测另一个文件名的可能性是无穷小的,但它不是密不透风的安全性,因为一个用户可能会给另一个文件提供访问权限。
答案 4 :(得分:0)
brownpaperpackage.aspx?ID = {GUID}
在media.aspx的Load事件中,验证用户是否已通过身份验证,然后验证用户是否有权查看媒体,如果有,则将媒体作为流加载并将其提供给页面的响应正如Spikolynn所示。
为什么这样?它易于编码,您可以获得ASP.NET和IIS身份验证服务的所有好处,您可以从中找到请求媒体的用户。将用户映射到媒体对象的访问列表非常简单。而Page在那里有请求对象。您还隐藏了媒体的名称,因此您无法分辨网址发生了什么。
如何阻止人们直接访问您的媒体?您的媒体文件无法存储在IIS虚拟目录中。如果是,则可以直接下载它们。您可以将它们作为字节数组(blob)存储在数据库中,也可以将它们存储在Web虚拟目录之外的磁盘上。用户必须通过ASP.NET访问文件
如何跟踪用户有权访问哪些媒体?您可以跟踪您的用户thorugh asp.net会员资格。这意味着每个用户在aspnet_users表中都有一个ID。使用id和文件名(或包含实际媒体的blob)为您的媒体创建一个表。然后你只需要创建一个连接两者的第三个表。此表将包含用户ID和媒体ID,表示此用户可以查看此媒体。使用用户ID(来自asp.net成员资格)和媒体ID(来自URL),您只需要
select count(*) from UserMedia where UserId = @UserGuid and MediaId = @MediaIdFromUrl
如果计数&gt; 0用户可以查看媒体。
您如何使用网址的示例:
<asp:image
runat="server"
ImageUrl="brownpaperpackage.aspx?id=53a2ea4(snip)76ca8b" />