Asp.net MVC+Linux+jexus环境中阻止静态html通过URL直接访问的解决过程

本文详细介绍了在使用ASP.NET MVC进行跨平台部署时,如何解决特定静态文件如HTML的访问控制问题。通过尝试多种方法,包括配置Web.config、URL重定向、更改文件后缀和使用自定义的IHttpHandler与IRouteHandler,最终实现了对静态文件的有效管理和权限验证。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

有一个项目,是用Asp.net MVC开发的,后来客户希望在系统项目不作过多改动的情况下,能够部署到Linux环境中,最终选择了使用Jexus(国产的,专为Asp.net 跨平台设计的)作为Asp.net程序的跨平台Web服务器部署环境(后来得知,可以使用 Nancy.Net 框架来实现跨平台),成功部署到Linux后,系统运行正常,后来,客户又提出新要求,对于html(有一些第三方投递过来的数据文件,放在其它目录,没有保存在View下的视图目录中)这种静态文件不能直接通过URL来访问,需要经过系统验证才可以正常访问,结果就开始了后面费劲费时的苦逼过程。

一、觉得很简单,直接使用最常用的方法

1) Web.config文件中增加以下配置:

 <configuration>
   <system.webServer>
    
    <!--所有静态文件都要走路由-->
    <modules runAllManagedModulesForAllRequests="true" />
   <system.webServer>
</configuration>

2) 修改路由规则,在App_Start文件夹下RouteConfig.cs文件中的RegisterRoutes方法

 public static void RegisterRoutes(RouteCollection routes)
        {
            //所有静态文件都要走路由,加上此代码
             routes.RouteExistingFiles = true;

            //系统默认生成的
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");       

            //Content、Scripts中有js、css等文件,不能走路由
            routes.IgnoreRoute("Content/{*relpath}");
            routes.IgnoreRoute("Scripts/{*relpath}");


            //html文件路由匹配,加上此代码
             routes.MapRoute(name: "htmlData",
                url: "File/Data/{*fileName}",
                defaults: new { controller = "Login", action = "Index" });

            //系统默认生成的
            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Login", action = "Index", id = UrlParameter.Optional }
            );
        }

3) 生成测试,结果,windows和Linux完全无效,跑到网上百度一下,都说这是Asp.net mvc3的方法,对Asp.net mvc3有效,我的项目是Asp.net mvc4的,折腾了好些时间,就是不行;分析发现,html等常用的静态文件类型完全没有进入asp.net mvc的生命周期,请求到达Web服务器后,如果是静态文件,IIS或jexus直接去磁盘上查找,找到直接返回,没找到,再经过 Asp.net mvc来找 ,所以问题点是:怎样让html等静态 文件进入asp.net mvc的生命周期?

二、URL重定向,Jexus中设置访问.html文件时,重定向到一个中间的控制器的Action

原理:重定向到控制器后,就进入了Asp.net MVC的生命周期,这时就可以很容易判断是否授权登录访问了

1) 在Controller中增加Action

        [Authorize]    //验证是否登录,不然会跳转到,需在Web.config中配置
        public ActionResult CheckGetData()
        {
            .....省略
            StreamReader sr=new StreamReader(fileName);
            string str=sr.ReadToEnd();
            sr.Close();
            Reponse.ContentType="text/html";
            Response.Write(str);
            .....省略
        }

 Web.config配置:

<configuration> 
  <system.web> 
  <!--非登录时将直接跳转至登录页面-->
   <authentication mode="Forms">
     <forms loginUrl="~/Login/Index/"></forms>
   </authentication>
   
  </system.web>
</configuration>

2) 在jexus/siteconf文件夹找到站点配置文件,配置UrlRewrite:

rewrite=*.html /Test/CheckGetData/

3) 生成并测试,结果:html文件可正常读取,如果只是独立的html文件没有引用其它任何文件(js、css等),可以正常显示,否则,html中引用的自己相对路径js、css、jpg等全部都变成了http://localhost/Test/CheckGetData/scripts/xxx.js、

http://localhost/Test/CheckGetData/content/xxx.jpg、

http://localhost/Test/CheckGetData/content/xxx.css等形式,

分析发现,html、content、scripts在项目中是在另外的文件夹中,而非View下,此种方法是通过路由的路径去加载文件的,肯定不行!

三、直接更改html的后缀为

1) 将html的后缀改为aspx;

2) 结合上述“一"中的方法;

3) 生成并测试,结果:不行,要么直接跳转到登录页,要么显示的是乱码;

四、使用实现的IHttpHandler、IRouteHandler接口

1) 将html的后缀改为aspx;

2) 在项目中新建StaticHttpHandler项目或cs文件,实现代码如下:

    //继承IHttpHandler
    public class StaticHttpHandler:IHttpHandler
    {
       //注意是RequestContext类型
       public StaticHttpHandler(RequestContext requestContext)
       {
           ProcessRequest(requestContext);
       }

       //注意是RequestContext类型
       private void ProcessRequest(RequestContext requestContext)
       {
           var request = requestContext.HttpContext.Request;

           //请求过滤判断
           if (request.Url.ToString().ToLower().Contains(".aspx"))
           {
               //未登录授权
               if (requestContext.HttpContext.User == null || !requestContext.HttpContext.User.Identity.IsAuthenticated)
               {                
                   requestContext.HttpContext.Response.Redirect("/Login/Index/");               
               }
               else
               {
                   requestContext.HttpContext.Response.ContentType = "text/html";
                                  
                 requestContext.HttpContext.Response.WriteFile(request.Url.AbsolutePath);
                   requestContext.HttpContext.Response.End();
               }
           }
       }

       //实现IHttpHandler中的方法
       public void ProcessRequest(HttpContext context)
       {
       }

      //实现IHttpHandler中的方法
      public  bool IsReusable 
      { 
          get{return true;}
      }
    }

3) 在项目中新建StaticRouteHandler项目或cs文件,实现代码如下:

//继承IRouteHandler
public class StaticRouteHandler : IRouteHandler
    {
        //实现IRouteHandler中的GetHttpHandler方法,返回一个HttpHandler
        public IHttpHandler GetHttpHandler(RequestContext requestContext)
        {
            return new StaticHttpHandler(requestContext);
        }
    }

4) 2) 修改路由规则,在App_Start文件夹下RouteConfig.cs文件中的RegisterRoutes方法

 public static void RegisterRoutes(RouteCollection routes)
        {
            //所有静态文件都要走路由,加上此代码
             routes.RouteExistingFiles = true;

            //系统默认生成的
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");       

            //Content、Scripts中有js、css等文件,不能走路由
            routes.IgnoreRoute("Content/{*relpath}");
            routes.IgnoreRoute("Scripts/{*relpath}");


            //html文件路由匹配,加上此代码
            routes.Add("StaticHttpHandler",
                 new Route("Files/Data/{*fileName}", new StaticRouteHandler()));

            //系统默认生成的
            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Login", action = "Index", id = UrlParameter.Optional }
            );
        }

5) 生成并测试,结果:达到目的!

 

总结:

1) 常用的html、jpg等静态文件Web服务器(IIS、jexus等)会直接到磁盘上匹配查找返回,不经过Asp.net的生命周期,所以就无法对其进行验证;

2) 对某些静态文件的后缀改为aspx(文件结构实质没质)有时候能解决一些问题;

3) 可以对于些特殊文件的请求使用UrlRewrite(一般可以是IIS等自带的重定向功能,也可以使用微软的UrlRewrite.Net插件,使用Nuget在项目中引用)功能隐藏原始的URL,有一定的安全保护作用;

4) 需要学习理解Asp.net 的Http请求流程、IHttpHandler、IRouteHandler、IHttpHandlerFactory 和IHttpModule的相关原理知识,这些知识道对Asp.net WebForm和Asp.net MVC都适用;

5) 可以使用Nancy.Net框架来开发.net的跨平台Web应用;

最后,本文章中的解决办法及出现的结果只是本人遇到的,并不代表一定是这种形式和结果,目的也是让供大家参考,希望有帮助,同时自己也加强记忆及以后翻阅!

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值