开发者

Check for a static file during Application_BeginRequest?

开发者 https://www.devze.com 2023-03-20 04:01 出处:网络
I have a Global.asx file that needs to do custom authentication, auditing and profiling stuff. This is needed because it supports a SAML based SSO system and needs to override the normal .Net authenti

I have a Global.asx file that needs to do custom authentication, auditing and profiling stuff. This is needed because it supports a SAML based SSO system and needs to override the normal .Net authentication (which doesn't support either SAML or mixed authentication)

I don't want to fire it for static files, such as .js, .css, .png, etc

In Cassini/WebDev and IIS7 it does.

What I want to have is some simple check, like a this.Request.IsStaticFile (which doesn't exist, unfortunately) to identify the static files.

I realise that this would be fairly simple to write, but it feels like something that must already exist - IIS has already applied caching policy stuff for the static files and so on.

I need a code solution, rather than an IIS config change one.

Update

This is my current workaround:

/// <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 exten开发者_如何转开发d.</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);
}

This works and is quick enough, but feels horribly clunky. In particular relying on extensions is going to be error prone if we add new static files not thought of.

Is there a better way without changing the IIS config?


You might be able to check which handler is dealing with the request.

In IIS6 only .net files, eg aspx are mapped to a handler that does stuff.

In IIS7 with the integrated pipeline, everything routes through .net, which is normally a good thing. Different handlers still deal with different file types though. In particular I believe the staticfilehandler is the one you need to check for. The httpcontext.handler property should allow you to figure it out.

You could create an extension method to add that IsStatic method...

Simon


There are a few options:

  • Adding authorization element and deny none for those paths that you do not need any authentication and contains your static files
  • You are using integrated pipeline. Turn it off on your IIS 7.


There is no doubt that you need to create a custom extension method because ASP.NET routing engine uses this code to decide whether a file exist,

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

You will not able to decide whether the request is static in Application_BeginRequest using context.handler because Routing Module may change the handler and this module always execute after Application_BeginRequest. My suggestion is to use the similar code which ASP.NEt routing engine uses.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号