AJAX callbacks and Forms authentication

Damir Dobric Posts

Next talks:

 

    

Follow me on Twitter: #ddobric



 

 

Archives

When implementing ASP.NET applications which make usage of AJAX and Windows Forms Authentication, there are few critical issues you have to be aware of. in this post you can find few very interesting information related to AJAX and FormsAuthentication.

Problem Description

Assume there is an ASP.NET application which use Windows Forms authentication and has a page called WebFormSessionTest.Aspx. Additionally the application is configured to use FormsAuthentication when user requests this page. This is a common scenario based on forms authentication in ASP.NET.

To configure application like this we would usually change web.config as shown below:

<authentication mode="Forms">
 <forms name=".MYCOOKIE" loginUrl="Login.aspx" protection="All" timeout="15" path="/" />
</authentication>

Please note the attribute timeout="15" in this example. This value defines the validity time the token (cookie), which is internally created after successfully login. It means, the user will be required to login again if the user has no taken any action for more than 15 minutes. Forcing the user to take a logon again means "redirecting of user to "Login.aspx" page (defined by attribute 'loginUrl').
Assuming that this is well known scenario, I'm not going to describe it in more detail.

Now, imagine the page WebFormSessionTest.Aspx is designed to operate with AJAX callbacks. In other words this means the page implement interface ICallbackEventHandler.

The critical issue, which I would like to describe begins at the moment when the user initiate AJAX callback, which should be handled by page WebFormSessionTest.Aspx. For example, the AJAX callback is initiated on press of some button B in the browser. As long the windows forms security token is valid all will work fine. However, if the user was inactive for a while (e.g.: 17 minutes) the token will expire and next request should be redirected to Login.aspx. Unfortunately, this does not work. At least not the way you could make any usage of it.

When the AJAX request (callback) is received  by the ASP.NET server, the FormsAuthentication runtime finds out that the token is expired (actually the cookie '.MYCOOKIE' has expired) and redirects the request to the login page. This is fine, but after the Login.aspx page is rendered, usually the browser should show it to the user. Unfortunately this does not happen. Instead the user will not get any message, after pressing on button B. It means, user press button B and nothing happens. No any action, no any error, just nothing.

"Why it does happen nothing?"

The answer is very simple. When the JavaScript creates an AJAX request it expect to receive a stream, which contains some result. If the request has been successfully handled the result looks like:

     72|/wEWBQLOhofbCwKzmbmVDAK/7+btDAL0z6nBDAK/797tDBiuyu1InxdK8K0lSm1Dy9K0Jp5+ok

This string is consisted as :
          Lenght(EventValidationValue) | EventValidationValue + Result

In our case length is 72 and value is '/wEWBQLOhofbCwKzmbmVDAK..p5'. The 'ok' on the right side is returning AJAX  message. This is what is expected. Now, imagine what happen when instead of this text the HTML code of the login page is returned. The JavaScript AJAX runtime does not know what to do with retrieved HTML code and unfortunately, just ignores it.

As result of this behavior AJAX will no more work in the application, as long some postback is initiated.

Solution

After some experimenting, fiddlering and reflectoring the solution looks like:

1. Check in Global.ASAX.cs if the request is none-authenticated AJAX request. (Assuming ScriptManage.AuthenticationService is not used).
2. If it is not just proceed.
3. If it is none-authenticated AJAX callback, enforce redirecting to login page by appending some additional parameter.
4. The Login.aspx page checks for additional parameter. If found the page will know that is is in callback context. Note that AJAX-callback has to be checked in Global.Asax.cs, because Login page is always invoked by redirect even if previous request has been AJAX callback.
5. If the Login page is called within AJAX callback (additional parameter is contained in request) we send the browser expected AJAX stream instead of rendered Login.aspx html. In this stream we append some marker, which indicates that the tokens has been expired.
6. Adopt AJAX java script handler function to be able to catch this information.

Putting all together:

GlobalAsax.cs: (Steps 1, 2 and 3):

Here is the code to be appended in the Global.Asax.cs:

 image

Login.cs (Steps 4 and 5):
Here is the code to be appended in the Login.cs:

image 

The string returned here can be parsed by java script handler as a valid response. Response.End() ensures that Login.ascx HTML is not rendered.

Java Script handler changes (Step 6)
Following JAVA script is used to create request (AJAX callback) and to handle failed authentication. The function go()
is called when the user presses the button B. After the request has been successfully processed by server handler the
function onSuccess is called. If the argument equals "authenticationfailed" teh response has been created by Login.cs and it menas
that the user is no more logged in.

image

Related article: http://developers.de/blogs/damir_dobric/archive/2006/10/09/939.aspx.


Posted Aug 18 2008, 10:20 PM by Damir Dobric
Filed under:

Comments

Ulhan wrote re: AJAX callbacks and Forms authentication
on 08-16-2012 2:06

If you haven't done so already, I think you just need to set the dafuelt url in the forms tag (web.config like so)<forms loginUrl="blablabla.aspx" dafueltUrl="YourDefaultPage.aspx" />Give it a go and let us know how you get on.  +8Was this answer helpful?

developers.de is a .Net Community Blog powered by daenet GmbH.