1

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?

sharptooth
  • 167,383
  • 100
  • 513
  • 979
  • Could it be that those clients are not accepting your forms authentication cookie ticket, so .NET is placing the encrypted cookie value into the URL much like a cookieless session identifier. What happens if you hit that URL from a browser with all 3rd party cookies disabled? – Tommy Aug 20 '13 at 19:56
  • @Tommy: AFAIK there's `cookieless` parameter in `sessionState` and it's "use cookies no matter what the client says" by default and I don't change that setting anywhere. – sharptooth Aug 21 '13 at 07:01
  • Fair enough - that is the only thing I have seen that causes .NET to inject a random character string like that, however, it typically is not 290+ characters (more like 30). – Tommy Aug 21 '13 at 13:41
  • @Tommy: I think the length of the string will depend on the amount of data in the session state, so 290 characters is not that abnormal. – sharptooth Aug 21 '13 at 13:50
  • I thought it was just an encoded identifier to identify the session ID on the server itself instead of the session data, since session data is stored server side? Interesting, I may have something to Google later today. – Tommy Aug 21 '13 at 14:00
  • Not to continue to beat a dead horse, but your issues sounds a lot like this one (independent of Session state, but rather the form auth ticket itself) - http://stackoverflow.com/questions/12228704/ie10-injects-token-into-net-mvc-links I didn't see any mention of the element in your edit – Tommy Aug 21 '13 at 14:17
  • @Tommy: Yes, that was exactly that thing. I added an answer. – sharptooth Sep 02 '13 at 10:26

1 Answers1

0

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.

Community
  • 1
  • 1
sharptooth
  • 167,383
  • 100
  • 513
  • 979
  • awesome - glad you got it figured out! I was less than certain, thus the comment vs an actual answer. Also, good job on the extra info, never knew the different default settings. – Tommy Sep 03 '13 at 00:48