ASP.NET forms authentication redirection exception

An exception is thrown when you use the method FormsAuthentication.RedirectFromLoginPage with some return URLs that are flagged as invalid, even though they aren't. This method is used to authenticate and redirect a validated user from the login page.

This problem occurs when an unauthenticated user tries to access a page that requires authentication and the URL of the page looks like this:

http://www.example.com/subsite/page.aspx?param=http://www.example.com/subsite2/something/else.aspx

Notice that the URL includes another URL as a parameter.

The user is redirected to the login page and ASP.NET automatically adds the return URL parameter. The URL of the authentication page will then be in the following format:

http://www.example.com/login.aspx?ReturnUrl=/subsite/page.aspx?param=http://www.example.com/subsite2/something/else.aspx

So it is basically an URL with a return URL that includes, in itself, an URL as a query string parameter.

The internal methods used by FormsAuthentication.RedirectFromLoginPage will assume this URL as invalid and the following exception will be thrown:

System.Web.HttpException The return URL specified for request redirection is invalid.
 at System.Web.Security.FormsAuthentication.GetReturnUrl(Boolean useDefaultIfAbsent)
 at System.Web.Security.FormsAuthentication.RedirectFromLoginPage(String userName, Boolean createPersistentCookie, String strCookiePath)
 at System.Web.Security.FormsAuthentication.RedirectFromLoginPage(String userName, Boolean createPersistentCookie)

A workaround for this is to use two separate method calls:

FormsAuthentication.SetAuthCookie(username, false);
Page.Response.Redirect(Page.Request["ReturnUrl"]);

The first call sets the authentication cookie and the second just redirects the user to the return URL.

It is better not to use it like that, though, as the return URL may be empty and in those cases the user should be redirected to the DefaultUrl. So a final solution could be:

string url = Page.Request["ReturnUrl"] as string;
 
if (!string.IsNullOrEmpty(url))
{
    FormsAuthentication.SetAuthCookie(username, false);
    Page.Response.Redirect(url);
}
else
{
    // there is no URL, RedirectFromLoginPage can be safely used to redirect to the default URL
    FormsAuthentication.RedirectFromLoginPage(username, false);
}

You should put this in a separate method and add some exception catching or logging just to be sure.

Nuno Freitas
Posted by Nuno Freitas on July 30, 2013

Related articles