当前位置:编程学习 > C#/ASP.NET >>

如何控制用户不能直接访问某路径下的文件

情况说明:
某.net网站下有一路径存放报告图片,其路径为http://www.abc.com/report/
report路径下存放的是各类报告存档(图片或PDF格式)
现通过WEB.CONFIG 限制了未登录用户不能访问该路径下的任何文件。
现在的问题是如何控制用户只能看到他自己的报告,即便他能猜到其他路径。

a用户登录后,能访问到http://www.abc.com/report/a_report.jpg
b用户登录后,能访问到http://www.abc.com/report/b_report.jpg
但a用户登录后,不能直接通过浏览器访问http://www.abc.com/report/b_report.jpg
请问该如何做? --------------------编程问答-------------------- 你这种要求用Forms验证已经不适用了。
方案1:报告不应该jpg存放。 你可以即时生成一个报告。
方案2:做一个图片查看页,在这个页中判断用户权限,同时配置图片防盗链禁止用户直接浏览器查看图片。
--------------------编程问答-------------------- 我想也是,JPG的文件知道路径应该就能访问的了吧 --------------------编程问答--------------------
引用 1 楼 banian_cn 的回复:
你这种要求用Forms验证已经不适用了。
方案1:报告不应该jpg存放。 你可以即时生成一个报告。
方案2:做一个图片查看页,在这个页中判断用户权限,同时配置图片防盗链禁止用户直接浏览器查看图片。

Forms验证只能满足匿名用户不能访问,对于已登录用户,需要的是另外的补充方案
方案一:报告有生成电子版报告,但客户还是要求要看原件,原件是照片照的报告原件,存成JPG格式了,所以JPG或PDF是必须的。
方案二:可以做图片查看页,实现按权限访问。但报告还是存放在REPORT路径下啊,熟悉一点的人都知道通过图片属性查看的路径,还是可以通过路径访问到其他报告图片啊
所以问题的关键是:
能否配置所有用户都不能直接通过路径访问REPORT路径下的文件。用户只能通过图片查看页访问要看的报告? --------------------编程问答-------------------- 为什么一定要用户把REPORT路径下图片给用户看呢?
暂存到缓存中或者临时的虚假路径给用户看。而不是把真实的地址给用户。

就好像你商店买东西,人家是从柜台给你商品的,不会带着你去仓库给你东西。这样仓库就保密了。 --------------------编程问答--------------------
引用 4 楼 banian_cn 的回复:
为什么一定要用户把REPORT路径下图片给用户看呢?
暂存到缓存中或者临时的虚假路径给用户看。而不是把真实的地址给用户。

就好像你商店买东西,人家是从柜台给你商品的,不会带着你去仓库给你东西。这样仓库就保密了。

首先,REPORT路径下的图片是由管理人员上传的,上传到该指定路径下。
如果管理人员上传报告后,然后其他人员登录后,即可查看到自己的报告。
想过另一种方法实现,但还是觉得有问题
IIS配置REPORT路径不可浏览,上传的图片格式生成随机文件名,这样,别人就猜不到文件名,就无法直接通过URL查找了,然后图片查看页通过ID号调取图片。但问题是客户端通过图片属性还是会查看到图片的真实路径吧?
--------------------编程问答-------------------- 除了流媒体,客户所看到的的其它类型的资源(文字、图片、音频、视频等)都是下载到客户计算机的浏览器临时目录里面了吧。你及时不让用户看到图片地址(可以考虑前台屏蔽右键),有心的客户还是可以在本地看到的。

或者你可以把图片保存到数据库里面(后台上传后,读取保存到一个字段里面,上传的那个目录不对外开放),客户访问的时候,读取这个字段,客户端生成图片,这样的图片应该是没有地址的。 --------------------编程问答--------------------
引用 5 楼 seapen 的回复:
但问题是客户端通过图片属性还是会查看到图片的真实路径吧?

你到现在还不太明白,给你用户看的是临时路径或者虚拟路径。即便是用户查看图片属性的地址也是虚拟的临时。
我上面不是举例了么。
假设你是我一个客户,你要求看我的样品,我从仓库中拿出来给你看,你看完了,
我放回去(销毁临时路径/虚拟路径)了。
下次你能自己去仓库中自己去查看吗?显然不可以。 因为你没办法访问到仓库,也不知道放在仓库的什么地方。 --------------------编程问答-------------------- 首先你报告文件应该通过管理系统上传。 上传后有数据库记录路径。
访问的时候返回临时路径或者虚拟路径,而不是真实的路径。
你看用户看的不是真实路径,人家怎么可能从图片属性知道你的路径? --------------------编程问答-------------------- 直接转2进制码入数据库,这样就能保证其他人不通过程序无法查看图片
然后你在程序里再加针对个人的权限验证 --------------------编程问答-------------------- 如果你真想这样做,我觉得有一种很简单的方法,那就是对图片名称进行加密,而且也是比较有效的方法。

加密的方法很多种,自己上网找下,比如:md5、SHA1和SHA256等。

经过加密后,再适当加上一些规则,应该可以到达你要的效果。 --------------------编程问答--------------------
引用 8 楼 banian_cn 的回复:
首先你报告文件应该通过管理系统上传。 上传后有数据库记录路径。
访问的时候返回临时路径或者虚拟路径,而不是真实的路径。
你看用户看的不是真实路径,人家怎么可能从图片属性知道你的路径?

谢谢,能否给个代码示例?之前没接触过虚拟路径 --------------------编程问答-------------------- 我倒是有个办法,有点笨,就是图片和文件名的命名都是以 用户名_数字, 做一个图片查看页,在这个界面访问的时候解析请求的的用户名和 文件名的前缀是否一样。不一样就不给查看。 --------------------编程问答--------------------
引用 11 楼 seapen 的回复:
谢谢,能否给个代码示例?之前没接触过虚拟路径


ASP.NET PreventDirectLink防盗链功能的实现实例,本程序运行于.NET FrameWork4.0版本,程序逻辑如下: 
  // 判断是否是本地引用,如果是则返回给客户端正确的图片 
   // 这里的判断就是用到了http请求中所记录的页信息 
   // 如果是网站,可将“localhost”修改为网站地址,例如:192.168.1.118 
   if (context.Request.UrlReferrer.Host == "localhost") 
   { 
   // 设置客户端缓冲中文件过期时间为0,即立即过期。 
   context.Response.Expires = 0; 
   // 清空服务器端为此会话开辟的输出缓存 
   context.Response.Clear(); 
   // 获得文件类型 
   context.Response.ContentType = "image/jpg"; 
   // 将请求文件写入到输出缓存中 
   context.Response.WriteFile(context.Request.PhysicalPath); 
   // 将输出缓存中的信息传送到客户端 
   context.Response.End(); 
   } 
   // 如果不是本地引用,则属于盗链引用,返回给客户端错误的图片 
   else 
   { 
   // 设置客户端缓冲中文件过期时间为0,即立即过期。 
   context.Response.Expires = 0; 
   // 清空服务器端为此会话开辟的输出缓存 
   context.Response.Clear(); 
   // 获得文件类型 
   context.Response.ContentType = "image/jpg"; 
   // 将特殊的报告错误的图片文件写入到输出缓存中 
   context.Response.WriteFile(context.Request.PhysicalApplicationPath + "Error.jpg"); 
   // 将输出缓存中的信息传送到客户端 
   context.Response.End();
--------------------编程问答--------------------
引用 13 楼 banian_cn 的回复:
Quote: 引用 11 楼 seapen 的回复:
谢谢,能否给个代码示例?之前没接触过虚拟路径


ASP.NET PreventDirectLink防盗链功能的实现实例,本程序运行于.NET FrameWork4.0版本,程序逻辑如下: 
  // 判断是否是本地引用,如果是则返回给客户端正确的图片 
   // 这里的判断就是用到了http请求中所记录的页信息 
   // 如果是网站,可将“localhost”修改为网站地址,例如:192.168.1.118 
   if (context.Request.UrlReferrer.Host == "localhost") 
   { 
   // 设置客户端缓冲中文件过期时间为0,即立即过期。 
   context.Response.Expires = 0; 
   // 清空服务器端为此会话开辟的输出缓存 
   context.Response.Clear(); 
   // 获得文件类型 
   context.Response.ContentType = "image/jpg"; 
   // 将请求文件写入到输出缓存中 
   context.Response.WriteFile(context.Request.PhysicalPath); 
   // 将输出缓存中的信息传送到客户端 
   context.Response.End(); 
   } 
   // 如果不是本地引用,则属于盗链引用,返回给客户端错误的图片 
   else 
   { 
   // 设置客户端缓冲中文件过期时间为0,即立即过期。 
   context.Response.Expires = 0; 
   // 清空服务器端为此会话开辟的输出缓存 
   context.Response.Clear(); 
   // 获得文件类型 
   context.Response.ContentType = "image/jpg"; 
   // 将特殊的报告错误的图片文件写入到输出缓存中 
   context.Response.WriteFile(context.Request.PhysicalApplicationPath + "Error.jpg"); 
   // 将输出缓存中的信息传送到客户端 
   context.Response.End();


亲,楼主要的不是这个防止图片盗链的效果。
他要的是 图片点右键不让看真实图片路径的效果。或者是不能保存原图的效果。 --------------------编程问答-------------------- 这个最好用一般处理程序处理,http管道拦截
补充:.NET技术 ,  ASP.NET
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,