views:

41

answers:

1

In an ASP.NET MVC application when using a custom Dependency Injection container (in this case, Unity), is it possible to intercept a request before GetControllerInstance is called to determine if forms authentication timeout has occurred?

I have the following in web.config:

<authentication mode="Forms">
  <forms loginUrl="~/Home/Index" timeout="10" defaultUrl="~/Home/Index"/>
</authentication>

If I log in to the website, wait for the timeout to occur, and then access another page (well, controller action), I would have expected the framework to take care of automatically redirecting me to ~/Home/Index. Instead it merrily goes along trying to create the new controller to handle the request which fails and I end up being redirected to our custom error page.

Looking at the callstack, I would think this needs to happen somewhere around MvcHandler.System.Web.IHttpHandler.ProcessRequest or MvcHandler.ProcessRequest .. certainly before DefaultControllerFactory.CreateController is called.

Has anyone else had to handle this situation?

Update: To be honest, I think this approach is probably incorrect and the better idea is to handle forms authentication timeout on the client-side with some javascript on the master page. I could then redirect to an action that will clear the session and return them to the login page similar to what is described here.

A: 

You could write a controller factory that wraps the unity controller factory (see my post on delegating decorators http://haacked.com/archive/2008/06/18/delegating-decorators.aspx for an example).

Then in your controller factory, you can override GetControllerInstance and wrap the delegate's call to GetControllerInstance with your before and after code.

Does that make sense?

Haacked
Hmm..ok so I already have a UnityControllerFactory written (http://stackoverflow.com/questions/2072121/in-asp-net-mvc2-using-unity-does-my-program-need-to-manage-the-lifetime-of-the-co/2072214#2072214). When I wrap this with another controller factory, how can I make this wrapped GetControllerInstance redirect to ~/Home/Index if the session is timed out? I thought I'd have to return an IController (or null)?
Jedidja
Oh - I guess when I wrap GetControllerInstance I can check for !HttpContext.Current.Request.IsAuthenticated, and then return my HomeController as well as change the requestContext.RouteData.Values["action"] to whatever I like :)
Jedidja
Yep, though you don't have to go through HttpContext.Current. GetControllerInstance receives a RequestContext. So what I'd do is: requestContext.HttpContext.Request.IsAuthenticatedThat way it'll be easier to unit test your new controller factory.
Haacked