[su_note note_color=”#fafafa”]I have recently found myself working on a project that needed federated authentication. While intrAnet sites could use SiteMinder agent, extranet sites could only do SAML via something like Shibboleth. Setting up a Service Provider with Shibboleth is fairly straightforward and well documented on their wiki. And it also works like a charm until you add Sitecore to the mix.[/su_note]
Crime
When you mix Shibboleth and Sitecore:
Error reading request body from browser (2746).
Boom! Shibboleth’s handler cannot get SAML assertions from the POST. Let’s find out why.
Forensic
First, we googled up everything we could on that issue and landed on a post in the Shibboleth user group. Someone somewhere was having exact same issue and posted about it two weeks ago. Didn’t help us but it did send us down the right path. We knew that something must have read from the HTTP stream on the way to Shibboleth. We were determined to find out who that was.
Step 1
The Shibboleth.sso
was in the ignoreUrlPrefixes
but that’s not the first processor in the httpRequestBegin
. Moving the guy to the front didn’t help.
Step 2
Looking through the preprocessRequest
we found our first suspect – SuppressFormValidation
This dude opens up Request.Form
inside a try/catch block to swallow certain errors. Clever but against the law. Put the guy under arrest and for that matter emptied the entire pipeline. No avail. The guy will go trial, of course, but it’s not our guy. Ours is still at large.
Step 3
We started disabling HTTP modules one by one. Mean, I know, but the only thing we could do. Disabled all but Sitecore.Nexus.Web.HttpModule
. The error was still there
Step 4
Disabled the Nexus entry point. Shibboleth works and opens the session with the attributes received from the Identity Provider… We got him!
Trial
Nexus wouldn’t talk. A well trained professional like him has everything obfuscated. Or has it?
We were able to get enough out of him to see that he was also opening the HTTP stream with Request.Form
attached to PreRequestHandlerExecute
. It was hard to understand why would he do that. As far as we could decrypt his words it was doing Context.Page.initialize()
and also setting the Sitecore.Configuration.State.Form
. This is something I would expect a pipeline processor in either preprocessRequest
or httpRequestBegin
would do. Probably a legacy from a long time ago.
Anyway. We had the criminal but we couldn’t isolate him. We needed an outside help.
Verdict
Guilty. Support request #441380 has been accepted as a bug. There was apparently another crime by the same guy earlier (#370128) and the solution for us was the same. Sitecore Support team offered a patch that basically allows you to do the following:
- Register another HTTP module to run before Nexus
- Configure a list of
AbsoluteIgnoreUrlprefixes
that would bypass Sitecore logic entirely - Have the new module detect the absolutely ignored URLs and silence the Nexus module
The name of the hero is … Sitecore.Support.Nexus.Web.HttpModuleDisabler
. Clever!
[su_divider][/su_divider]
I actually believe all ignore URLs should be ignored absolutely. If it needs to bypass Sitecore it should come through clean and untouched.
If you find yourself solving the same crime just ask the guys to share a fix #370128. This bug has not yet been prioritized for a product release.
Cheers!
Thank you, this article was tremendously helpful in confirming the exact problem that I am currently debugging. We will be requesting the patch from Sitecore based on the support identifier #441380.