【问题标题】:Check for a static file during Application_BeginRequest?在 Application_BeginRequest 期间检查静态文件?
【发布时间】:2011-10-04 08:49:59
【问题描述】:

我有一个 Global.asx 文件,它需要进行自定义身份验证、审核和分析。这是必需的,因为它支持基于 SAML 的 SSO 系统并且需要覆盖正常的 .Net 身份验证(不支持 SAML 或混合身份验证)

我不想为静态文件触发它,例如.js.css.png

在 Cassini/WebDev 和 IIS7 中可以。

我想要的是一些简单的检查,比如this.Request.IsStaticFile(不幸的是,它不存在)来识别静态文件。

我意识到这将是相当简单的编写,但感觉就像一些已经存在的东西 - IIS 已经为静态文件应用了缓存策略内容等等。

我需要一个代码解决方案,而不是一个 IIS 配置更改。

更新

这是我目前的解决方法:

/// <summary>Hold all the extensions we treat as static</summary>
static HashSet<string> allowedExtensions = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
    ".js", ".css", ".png", ...
};

/// <summary>Is this a request for a static file?</summary>
/// <param name="request">The HTTP request instance to extend.</param>
/// <returns>True if the request is for a static file on disk, false otherwise.</returns>
public static bool IsStaticFile(this HttpRequest request)
{
    string fileOnDisk = request.PhysicalPath;
    if (string.IsNullOrEmpty(fileOnDisk))
    {
        return false;
    }

    string extension = Path.GetExtension(fileOnDisk);

    return allowedExtensions.Contains(extension);
}

这行得通,而且速度足够快,但感觉非常笨拙。如果我们添加没有想到的新静态文件,尤其是依赖扩展将很容易出错。

在不改变 IIS 配置的情况下有没有更好的方法?

【问题讨论】:

    标签: asp.net asp.net-mvc global-asax static-files


    【解决方案1】:

    您也许可以检查哪个处理程序正在处理该请求。

    在 IIS6 中只有 .net 文件,例如 aspx 被映射到一个处理程序。

    在具有集成管道的 IIS7 中,所有内容都通过 .net 进行路由,这通常是一件好事。不过,不同的处理程序仍然处理不同的文件类型。特别是我相信 staticfilehandler 是您需要检查的。 httpcontext.handler 属性应该可以让您弄清楚。

    您可以创建一个扩展方法来添加该 IsStatic 方法...

    西蒙

    【讨论】:

    • 我意识到我可以编写自己的实现(就像我在问题中所说的那样),但这感觉就像重新发明轮子。 IIS 和 .Net 已经知道这是静态文件请求,因此应该有现有的方法来执行此操作。
    【解决方案2】:

    有几个选项:

    • 添加 authorization element 并拒绝那些不需要任何身份验证并包含静态文件的路径
    • 您正在使用集成管道。在 IIS 7 上将其关闭。

    【讨论】:

    • 我必须完全覆盖 .Net 的授权机制才能支持 SAML SSO(这就是为什么我首先需要在 Application_BeginRequest 中进行大量工作),所以选项 1 不可用。另外,就像我在问题中所说的那样,更改 IIS 配置不是一种选择 - 我需要一个代码解决方案。
    【解决方案3】:

    毫无疑问,您需要创建自定义扩展方法,因为 ASP.NET 路由引擎使用此代码来决定文件是否存在,

    if (!this.RouteExistingFiles)
    {
        string appRelativeCurrentExecutionFilePath = httpContext.Request.AppRelativeCurrentExecutionFilePath;
         if (((appRelativeCurrentExecutionFilePath != "~/") && (this._vpp != null)) && (this._vpp.FileExists(appRelativeCurrentExecutionFilePath) || this._vpp.DirectoryExists(appRelativeCurrentExecutionFilePath)))
         {
              return null;
           }
    }
    

    您将无法使用 context.handler 在 Application_BeginRequest 中确定请求是否是静态的,因为路由模块可能会更改处理程序,并且此模块始终在 Application_BeginRequest 之后执行。我的建议是使用 ASP.NET 路由引擎使用的类似代码。

    【讨论】:

      猜你喜欢
      • 2014-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-17
      • 2019-09-23
      • 2021-01-31
      • 1970-01-01
      相关资源
      最近更新 更多