views:

318

answers:

3

I've got an HTTPModule that does some role-based page access security (I'm having to retrofit some security into some code that we've acquired).

I've noticed that in one instance that it doesn't fire on a Server.Transfer.

Here's a snippet of the code:

        ' move to target page
    Select Case eTransferMethod
        Case TargetPageTransferMethod.Redirect
            Page.Response.Redirect(strPage, False)
        Case TargetPageTransferMethod.Transfer
            Context.Handler = Me
            Page.Server.Transfer(strPage)
        Case TargetPageTransferMethod.None
            ' Do nothing
    End Select

The case that I'm talking about here is the TargetPageTransferMethod.Transfer case. The page will be an .aspx page.

Now I know that AcquireRequestState is fired on other Server.Transfer calls in this code. In fact it gets fired on the postback when a button on the page transferred to is clicked. Ironically my security code is bypassed on the transfer to this page but denies access on the postback when this page's cancel button is clicked! :eek:

I'd post further details of the codebase but it's so convoluted and sprawling it'd be a nightmare to explain.

So basically I'm asking 'What might cause the AcquireRequestState event in an HTTPModule to not fire when a Server.Transfer is called?'

A: 

I can understand it being called on a post back, as that is another request from the client, but Server.Transfer doesn't initiate a new request, it transfers execution from one page to another.

As the AcquireRequestState event is fired "when ASP.NET acquires the current state (for example, session state) that is associated with the current request" - this would occur on the initial request from the browser, but not on the server transfer as the server didn't get another request, you're just asking it to process a different page.

A key comment is this one from the HttpServerUtility.Transfer documentation:

ASP.NET does not verify that the current user is authorized to view the resource delivered by the Transfer method. Although the ASP.NET authorization and authentication logic runs before the original resource handler is called, ASP.NET directly calls the handler indicated by the Transfer method and does not rerun authentication and authorization logic for the new resource. If your application's security policy requires clients to have appropriate authorization to access the resource, the application should force reauthorization or provide a custom access-control mechanism.

Zhaph - Ben Duguid
Yup you're right. I've just rechecked my initial proof of concept test site and I can only assume I was drunk when I did the initial tests. :(Going to have to rethink this idea of using an HTTPModule.
A: 

Server.Transfer doesn't reprocess the entire HTTP pipeline for the destination page. It just calls the destination page's HttpHandler. Because of this, you shouldn't see any of the earlier applicaton events get fired.

David
Yup, spot on, d'oh! See the above comment. :(
Bit embarrassed about this but I'm going to make Spooner's answer the question because he offered a solution as well. Thanks for the heads up though!
+3  A: 

The way to get around this is to create a custom HttpHandler that inherits the System.Web.UI.PageHandlerFactory class.

You can then override the GetHandler method which is called whenever a page instance is created, both on Response.Redirect and on Server.Transfer.

Register this new handler to use the "*.aspx" extension and all pages will automatically use the new handler. This allows you to do custom authorisation on Server.Transfer as well as use a dependency injection framework (e.g. MS Unity).

spooner