使用RouteExistingFiles属性限制对文件夹的访问

6 篇文章 0 订阅

RouteExistingFiles 属性

          当用户请求如图片、视频等静态文件资源时,asp.net会很高兴的定位文件位置并提供给用户,除非我们做了某些限制。有时我们需要做一些限制只能让所有者访问而不能让其他用户访问,一种简单的情况是通过web.config 文件配置进行限制,但在复杂的情况下,如果能够通过action/filter控制访问权限将是不错的选择,为了实现这个目的需要将静态文件请求通过MVC pipeline 进行处理,而MVC的RouteExistingFiles属性恰好能做到,通过将RouteExistingFiles属性设置为true,MVC将处理这些请求,而不是由iis处理这些静态文件请求。

      下面讨论如何实现,例如:

下面是 Global.asax.cs文件

1
2
3
4
5
6
7
8
9
10
public static void RegisterRoutes(RouteCollection routes)
{
     routes.IgnoreRoute( "{resource}.axd/{*pathInfo}" );
 
     routes.MapRoute(
         "Default" ,
         "{controller}/{action}/{id}" ,
         new { controller = "Home" , action = "Index" , id = UrlParameter.Optional }
     );
}

设置RouteExistingFiles = true,禁止 IIS 处理这些存在的静态文件请求并发送结果

1
2
3
4
5
6
7
public static void RegisterRoutes(RouteCollection routes)
{
     routes.IgnoreRoute( "{resource}.axd/{*pathInfo}" );
 
     routes.RouteExistingFiles = true ;
     ...
}

下一步,需要定义一个新的路由处理这些情况,URL模式部分看起来比较象物理路径,但不用如此,这里只是个例子.

1
2
3
4
5
routes.MapRoute(
     "photo" ,
     "premium/photos/{accountNo}/{image}" ,
     new { controller = "Photo" , action = "Index" }
);

如你所想,我们需要新建controller和action ,index方法将返回请求的完整路径.

1
2
3
4
5
6
7
public class PhotoController : Controller
{
     public FileResult Index()
     {
         return File(Request.RawUrl, "image/jpeg" );
     }
}

但我们的index方法仍然不安全,需要添加验证,通过自定义authorize 属性 ,这个自定义属性通过检查url中的accountNo 和存在session的accountNo作对比,如果不匹配,则返回401

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class PhotoAuthorizeAttribute : AuthorizeAttribute
{
     protected override bool AuthorizeCore(HttpContextBase httpContext)
     {
         if ( base .AuthorizeCore(httpContext))
         {
             var accountNo = httpContext.Request.RequestContext.RouteData.Values[ "accountNo" ];
 
             if (accountNo != null && httpContext.Session[ "AccountNo" ].ToString() == accountNo.ToString())
             {
                 return true ;
             }
 
             return false ;
         }
 
         return false ;
     }
}

我们需要给返回静态文件资源的action加上自定义权限验证属性PhotoAuthorize attribute.

1
2
3
4
5
[PhotoAuthorize]
public FileResult Index()
{
     return File(Request.RawUrl, "image/jpeg" );
}

但有一个重要的问题是,一旦把RouteExistingFiles属性设置为true,Content文件夹下的styles 和 javascript 的文文件同样会被阻止,这是个大问题,这个属性的影响是全局的,那如何发送这些css, js文件?为它们单独创建controller和action是个不好的方法,幸运的是还有IgnoreRoutemethod方法可以方便解决这个问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public static void RegisterRoutes(RouteCollection routes)
{
     routes.IgnoreRoute( "{resource}.axd/{*pathInfo}" );
 
     routes.IgnoreRoute( "Content/{*relpath}" );
 
     routes.RouteExistingFiles = true ;
 
     routes.MapRoute(
         "photo" ,
         "premium/photos/{accountNo}/{image}" ,
         new { controller = "Photo" , action = "Index" }
     );
 
     routes.MapRoute(
         "Default" ,
         "{controller}/{action}/{id}" ,
         new { controller = "Home" , action = "Index" , id = UrlParameter.Optional }
     );
}

IgnoreRoute 告诉路由模块 routing module 不要处理这些请求,请注意:需要在RouteExistingFiles=true之前调用ignoreroute方法。.

避免客户端缓存

最后一个问题就是浏览器缓存。浏览器会缓存图片,未授权用户能够看到这些缓存的受限图片,通过 OutputCache attribute告诉浏览器不要缓存这些图片即可

1
2
3
4
5
6
[PhotoAuthorize]
[OutputCache(NoStore = true , Duration = 0, VaryByParam = "None" )]
public FileResult Index()
{
     return File(Request.RawUrl, "image/jpeg" );
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值