This is the first in a 4 part series on building a single sign on provider using the ASP.NET platform (ASP.NET and WCF). Originally, I wrote the article as a single post but it was pretty long, even for me.
Part 1 addresses the problem in general and how I decided to architect it.
Part 2 discusses setting up FormsAuthentication for WCF
Part 3 discusses JSONP communication between the client and WCF
Part 4 describes the implementation details and includes the source code.
Part 1: Planning an SSO Solution
We're using a custom FormsAuthentication provider and I was asked last week to integrate single sign on into our application. Since we don't have a single sign on service I had to build one from scratch. I found a few solutions I thought would work, but I had erroneously assumed that the applications would all live on the same domain. I figured we'd place each application in a separate sub-domain, until I was told that there was no guarantee the applications using my SSO solution would live under the same domain.
I dug around and considered the two public SSO solutions I am most familiar with: Google's and Microsoft LiveID. Here's what I came up with as a result:
Guess what? I can hear you laughing from here. Disclaimer: I suck at Visio.
Here's a description of what you're seeing:
- Client – a web browser attempting to access a web application which has been secured by a trusted SSO service.
- Application – a web application which delegates the validation of user credentials to a centralized authentication service.
- SSO Service – a centralized repository of user credentials and (potentially) profile data managed by a trusted 3rd party.
The SSO service has no UI whatsoever. All communication between the client and SSO service is done via cross-domain ajax calls (JSONP). While this is no requirement of SSO in general, the requirement given to me was that the client would not leave the application they were attempting to access. The benefit here is that each application retains control over the look and feel of all pages viewed by the client.
Here's how the process flows:
- When an unauthenticated client requests a secured resource from the application that client is redirected to an authentication page.
- The authentication page makes a request (via JSONP) to the SSO service for a token which can then be presented to the application as evidence of the client's identity with the SSO service.
- If the client has already authenticated with the SSO service and has an active session then skip to step #7 otherwise the request is denied.
- An unauthenticated client (SSO authentication) is redirected to a login page where the client then submits credentials for the SSO service.
- Upon submitting a valid set of credentials to the SSO service the client receives a cookie containing a token which is valid for the SSO service.
- Now that the client has successfully authenticated with the SSO service the client is redirected back to the application's authentication page (step #2).
- The client now submits the SSO token to the application. The application verifies the token with the SSO service by forwarding it and asking if it is a valid token.
- The SSO service responds to the application with a flag indicating wither or not the submitted token is valid or not. Potentially, the SSO service could also provide additional information regarding the identity of the client. If the token was valid, the application then responds to the client with a token of it's own which identifies the client to the application.
- The client, now authenticated with both the SSO service as well as the application, resubmits the request for the resource from step #1.
Messages over JSONP are not considered secure, so at the very least you will want to make sure and use SSL to protect communication with the SSO service.
Also, EVAL is called on the JSONP response to execute the callback returned by the service. If the service is vulnerable to injection attacks and the scripts injected into the service are returned somehow via JSONP then those scripts will be executed on the client.
There are security issues you should consider when using JSONP or any type of cross-domain communication.
There are those among you who would be able to implement the entire solution on your own at this point – none of this is cutting edge. Stay tuned for the next installment on setting up FormsAuthentication with WCF.
Tags: .NET Framework 3.5, AJAX, ASP.NET, WCF