Michael C. Gates
Michael C. Gates

Reputation: 992

Continue processing page with HttpHandler for securing subfolder

I created an HttpHandler to check user authorization in a specific directory. It is running, and tested, however, it doesn't seem to continue to process the page after it runs the ProcessRequest method. This is the basics of it:

public AdminProtectionHandler() { }

bool IHttpHandler.IsReusable { get { return true; } }    

void IHttpHandler.ProcessRequest(HttpContext context) {
    if (!Sessions.CurrentUser.Authenticated)
    {
        context.Response.Write("ACCESS DENIED");
        context.Response.End();
    }
}

In the web.Config of the subfolder:

<httpHandlers>
    <add verb="*" path="*" validate="true" type="AdminProtectionHandler" />        
</httpHandlers>

When not authenticated, I get the response as expected: ACCESS DENIED

When authenticated, I get a blank page, as if the request just stopped.

Upvotes: 2

Views: 1855

Answers (1)

rism
rism

Reputation: 12142

You've confused HttpHandler with HttpModule.

An HttpHandler does exactly that: handle the request. Since you only handle the unauthorized condition, you only get content when not authorized.

An HttpModule will examine a request and either do or not do something with it, possibly letting it pass through to a handler, possibly short circuiting the request if it doesn't like what it sees.

The point is multiple HttpModules run per request but only one HttpHandler per request.

When authenticated, I get a blank page, as if the request just stopped

Because with respect to your handler, it has.

The HttpApplication pipeline continues to run firing additional events after your handler returns, but no additional content is generated.

You typically wouldn't perform authentication checks in your handler. You'd do it before that time and the framework already has this built in for various authentication modes.

But to help you on your present path, you'd do something more like below:

public class MyModule : IHttpModule {

     public void Init(HttpApplication app) {
        app.PostResolveRequestCache += (src, args) => {
           if (!Sessions.CurrentUser.Authenticated) {
                app.Context.RemapHandler(new MyHandler());
           }
        }
     }

     public void Dispose() { }
}

public class MyHandler : IHttpHandler
{
    public bool IsReusable { get { return true; } }
    public void ProcessRequest(HttpContext ctx)
    {
        ctx.Response.ContentType = "text/plain";
        ctx.Response.Write("ACCESS DENIED");
        context.Response.End();
    }
}

<modules>
  <remove name="FormsAuthentication" />
  <add name="MyModule" type="MyNamespace.MyModule" />
</modules>
/// Remove your httpHandler web config section.

This way your handler is only remapped if the request is not authenticated. Otherwise processing continues as per usual.

Upvotes: 5

Related Questions