As I get into more and more details on WIF and all the WS-Federation related stuff, I’ve been extremely interested in how single sign out should work. While single sign-on is easy, the Identity Provider Security Token Service (IP-STS) maintains its own session (probably protected with Forms Authentication or similar mechanism) and responds to wasignin1.0 requests from federated applications (Relying Parties), the single sign-out should somehow involve sending requests to each single authenticated Relying Party to inform it that the user is about to sign out of the Identity Provider.
Unfortunately, the STS template generated by Visual Studio when you “Add STS Reference” and “Create new STS” is not very helpful. What it does it signs you out from a single RP:
Fortunately, there’s this fantastic book by Vittorio Bertocci, Programming Windows Identity Foundation, which covers WIF deeply while being very clear and understandable at the same time. Vittorio explains that the RP-side modules (FAM & SAM, responsible for negotiating and maintaining a session between the RP and the IP) respond to wsignoutcleanup1.0 message appended to any request to an RP page and the result of such request would be:
a) to destroy the session at the RP’s side
b) to return an image of a green check mark image to mark a successfull operation
What a handy idea! The sign-out from multie RPs, according to Vittorio, is then:
a) to keep track of consecutive RPs signing in via the IP at the IP side, Vittorio suggests that this information could be persisted in a cookie to save the IP’s resources but probably the session could also be used
b) to return a page containing multiple images with src attribute pointing to consecutive RPs with wsignoutcleanup1.0 when wasignout1.0 is requested from the IP (Vittorio’s book, page 121)
Unfortunately, few details are missing here and this is the motivation of this entry.
First, it’s not possible to get a complete solution containing all the files. A link at O’Reilly site, which should probably point to book’s code samples, points to the WIF SDK which does not contain this particular example.
I’ve decided then to provide an implementation of this SingleSignOnManager class, which contains two methods. The SignOut is used in the above snippet to get the list of all RPs authenticated during the current user session. Another method, RegisterRP is used in the GetOutputClaimsIdentity of a SecurityTokenService at the IP’s side to store the information of the RP which authenticates via the IP:
The SingleSignOnManager would be as follows:
As you can see, each consecutive RP is added to the list of RPs remembered in a cookie created by the IP. The only possible drawback of this implementation is that there’s a chance that the cookie will overgrow the legal limit of a cookie size.
The last but not least detail is to add two controls to the IP’s authentication page (Default.aspx in the template example), a label lblSignoutText and a panel SignoutLinks.
When you build your custom test environment consisting of a IP-STS and two (or more) RPs, as the result of a sign-out (the easiest way to trigger the sign-out is to use the wif:FederatedPassiveSignInStatus control which shows a sign-out link) you’ll note that signing out no loger incorrectly redirects to the login page in a context of a single RP (leaving all other RPs logged in!) but rather it shows a page with links to consecutive RPs and images of green check marks next to all links to indicate the succesfull sign-out.
A next step of my research is to build a “virtualized” IP-STS, which serves as the IP for different data sources but from a single web application.