Question

In my ASP.NET MVC3 application I have the following route definitions:

routes.MapRoute( "Sso", "MyController/Sso",
    new { controller = "MyController", action="Sso" } );
routes.MapRoute( "Settings", "MyController/Settings/{objectId}",
    new { controller = "MyController", action="Settings", objectId = @"" } );

and inside MyController I have this:

[My]
public ActionResult Sso( list of parameters )
{
    //blah - nothing that would yield a redirect, then
    FormsAuthentication.SetAuthCookie("MagicSso." + someGuid, false);
    return RedirectToAction("Settings", new { objectId = someGuid } );
}

and MyAttribute class inherits from System.Web.Mvc.ActionFilterAttribute and overrides OnResultExecuted() and the latter logs the value of ResultExecutedContext.HttpContext.Response.RedirectLocation.

In test it works just fine and when OnResultExecuted() runs it logs /MyAccount/Settings/some-guid-as-expected-here as redirection target exactly as expected. Also note that objectId is properly mapped so clearly the right route is matched.

However in production the following happens. A request comes to https://my.domain.name/MyController/Sso and when OnResultExecuted() runs it logs something like /some-very-long-string-290-characters-long-here/MyAccount/Settings/some-guid-as-expected-here as redirection target. And it looks like that's what the users receive and try to follow - I see requests in HTTPERR logs to this URL coming from the outer worlds and failing with code 400 (bad request).

I'd rather not publish the random string here because I'm not sure if it reveals any sensitive data. It contains the same number of characters every time, always starts with (F( and always ends with )) and all the other characters are uppercase and lowercase latin characters and numbers separated with occasional dashes and underscores placed without any obvious rules. Other than that it looks completely random.

After lots of search I'm pretty sure that the weird looking string is the ASP.NET session state sent to the client in "cookieless" fashion. So I checked that in my application System.Web.HttpSessionStateBase.CookieMode returns UseCookies and System.Web.HttpSessionStateBase.IsCookieless returns false and also (System.Web.Configuration.SessionStateSection)System.Web.Configuration.WebConfigurationManager.GetSection("system.web/sessionState").Cookieless returns UseCookies. So I'm more or less sure that ASP.NET is configured to return the session state as cookies no matter what the client prefers.

Why would RedirectToAction() suddenly inject some random looking string similar to encoded session state into the redirect target?

Was it helpful?

Solution

Turns out there're two completely separate settings - one from system.web/sessionState and the other one from system.web/authentication/forms/cookieless and they have different values by default. The latter has UseDeviceProfile by default and so it will sometimes inject the Forms authentication token into the URL.

In our case this configuration made no sense - if the user has no cookies support he can't use our site because it relies on cookies heavily, so we just changes system.web/authentication/forms/cookieless to UseCookies.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top