In one of my last entries, I’ve described an inconsistent behavior of different web browsers which occurs when users click the Back button in their browsers.
This subtle issue causes a deadful issue in an environment built around the ADFS2.
The problem is as follows: you have your applications federated with the ADFS2, tons of them. Each application has the “SignOff” button which takes users to ADFS2. ADFS2 renders the signoff page (containing iframes with urls with wsignoutcleanup1.0) which uses a jscript to redirect to the login page (if the wreply parameter is included).
One of our clients alarmed us that signing off from applications still allows users to see the last visited page. Upon closer inspection, it turned out that because of the way Opera, Firefox and Chrome treat “redirect” pages (please consult the mentioned blog entry), clicking Back on the login page (after succesful sign off) takes users back to the last page they visited (the one they clicked “sign off” on). And because most pages are read from a disc cache, the page is rendered even though a user hasjust signed off from the application!
Luckily, when ADFS2 is deployed, web pages have both *.aspx and *.cs available for modifications. There is a chance then to change the way the script is generated in the SignOut.aspx page.
What you have to find out is to find a way to replace this script with the modified one.
When you open the SignOut.aspx.cs however, you will find out that there’s nothing much to do there:
Since I cannot replace the base class’ constructor – my new class will always call it. That’s unfortunate as the script is registered in the constructor, using ClientScript.RegisterStartupScript. But the ClientScriptManager class lacks a way to unregister scripts! Another unfortunate issue!
What I can do however, is to generate a new window.onload handler which will replace the one created by the script registered with an existing, base class code. The intention is to have the following structure of scripts in the SignOut page:
My proposal is then to change the SignOut.aspx.cs to:
There are few things to explain.
First as you can see, I introduce a new class between the core SignOutPage class and the actual SignOut page class. The introduced class creates two scripts and injects them to the generated web page. The first script is rendered using a reflection on the FederationPassiveAuthentication type – this is because the type is internal in the ADFS2 core libraries. The second script uses the JSEncode method which is rewritten to mimic the way ADFS2 implements it.
And this is it. This does the trick and solves the unfortunate issue. Newly introduced scripts prevents the application page to be seen when users press the Back button in their browsers.
Once again – for this to work, you have to copy the above SignOut.aspx.cs and replace the original one. Remember to save a backup copy of the original file. Also, altough the solution was tested in a development environment, I can’t be 100% sure that there are no unexpected side effects of this change.