Using a technique I found in one of the recent ASP.NET MVC books, I have an action method on a controller that returns a partial view for an ajax request and a full view actionresult for a normal get request -- it checks the IsAjaxRequest property of the Request object to determine which type of actionresult to return. The partial view returned by the action method returns the HTML to display a table of records from a database. The controller that contains the action method is tagged with the Authorize attribute so that only logged in users can call the controller's methods. I am using forms authentication with a 30-minute timeout and sliding expiration.
The problem arises after the user's 30-minute timeout has been reached. Because the controller is marked with the Authorize attribute, a call to the action method after the expiration timeout redirects the user to the login page. However, because this is an ajax call, the html for my login page is returned and rendered in the middle of the page that should contain the HTML table of records that would normally be returned by the action method in the partial view. The ajax call is not really failing, just returning the html for the wrong page.
Has anyone encountered and dealt with this problem? I am trying to avoid having to move all of my server side code that handles ajax calls into a separate controller that does not require an authenticated user, but that seems like my only alternative at this point. Even that won't produce the behavior I would expect, because it will allow the user to continue using the web page even after the 30 minute timeout has been reached -- it will not redirect to the login page.
Thanks for any advice.
Edit
The solution below with the custom AuthorizeAttribute would seem to have me heading in the right direction, but I cannot even get to this code. It appears that the code in the custom AuthorizeAttribute is never reached after the expiration timeout is reached. It seems like forms authentication is causing a redirect to the login page long before the attribute code. The custom AuthorizeAttribute is the only one on my controller. I also have the following web.config values (the timeout value is set extremely low to trigger a timeout for testing):
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" timeout="1" slidingExpiration="true" defaultUrl="~/ErrorReport/Index" requireSSL="true" protection="All"/>
</authentication>
<authorization>
<deny users="?"/>
<allow users="*"/>
</authorization>
<location path="Content">
<system.web>
<authorization>
<allow users="*"/>
</authorization>
</system.web>
</location>
<location path="Scripts">
<system.web>
<authorization>
<allow users="*"/>
</authorization>
</system.web>
</location>
Are the authorization web.config elements getting in the way? Should I not be using them with ASP.NET MVC?