[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]
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.
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.
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.
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.
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
Disabled the Nexus entry point. Shibboleth works and opens the session with the attributes received from the Identity Provider… We got him!
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
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.
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
AbsoluteIgnoreUrlprefixesthat 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 …
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.