I recently was involved in designing enterprise software which contained several ASP.NET web sites and desktop applications. Since same users would use this software system a single-sign-on feature was necessary. Thus I took advantage of Microsoft Identity Foundation which is based on Claim Based Authentication. Also as the applications would be used by internal users, I used Active Directory Federation for authenticating users against an existing Active Directory.
Later I though what would be the solution if Claim Based Authentication did not fit in the solution? So I decided to design and implement a simple single-sign-on (SSO) authentication with WCF. This SSO has the following specifications:
- Only performs Authentication. It does not contain any role management capability. The reason is that roles and access rights are defined in the scope of each application (or sub-system) so it is left to be done by applications.
- It is based on Web Services so it can be consumed any technology that understands Web Services (e.g. Java apps.)
- It can support many kind of user storage, such as Active Directory, ASP.NET Application Services (ASPNETDB) , Custom Authentication etc.
- It can be used by Web, Desktop and Mobile applications.
Figure 1, Components of SSO
As seen in figure 1, user information can be retrieved from Active Directory, ASP.NET Application Services, Custom Database or 3rd Party Web Services. Components that encapsulate the details of each user storage or services are called Federations. This term is used by Microsoft in Windows Identity Foundation so we keep using that!
The Single Sign-On Service relies on Federation Services. Each federation service is simply a .NET Class Library that contains a class which implements an interface which is common between itself and SSO service. A federation module is plugged into SSO service via a configuration file. The Visual Studio solution that is downloadable at the bottom of this post includes a custom federation module that uses SQL Server to store the user information.
Client applications can consume the Web Service directly to perform sign-in, sign-out, authentication and other related operations. However, this solution includes a custom ASP.NET membership provider which allows ASP.NET applications consume SSO with no hassle. It also enables the existing ASP.NET applications to use this SSO service with a small configuration change.
Figure 2, Package diagram of SSO
Classes and Interfaces
The key classes and interfaces are as below:
- ISSOFederation Interface: is implemented by Federation classes.
- AuthenticatedUser: Is used by the federation classes and SSO service to represent a user. This type is also emitted by the service to the clients.
Figure 3, Key types of Common package
- CustomFederation: Implements ISSOFederation and encapsulates the details of authentication and user storage.
- SSOFederationHelper (SignInServices package): Provides a service to load the nominated federation service. Only one instance of the federation object exists (Singleton) so to plug another federation module the service must be restarted (e.g. restart the ISS web site).
Figure 4, SSOFederationHelper class
A federation object is plugged to the service using reflection. To do so, first the Fully Qualified Name of the federation type is placed in the Web.Config file:
This type is instanciated by reflection and provided to the consumers by SSOFederationHelper.FederationObject property. For example:
- SSOMembershipProvider (SSOClientServices package) is also a custom Asp.net membership provider. This class enables the ASP.NET applications take advantage of the SSOService without being dependent on it. The key point here is that all the ASP.NET applications that take advantage of SSO service must give a same name to the Asp.net membership cookie. Example:
timeout=“2880” name=“.SSOV1Auth“ />
The custom membership provider has a proprietary app.config file. This configuration file includes the WCF client configuration (e.g. binding configuration). However, the URI of the service is configured in the Web.config file of the ASP.NET client. For example, an ASP.NET client configures the membership providers as below:
The value of endPointUri entry will be used to configure the service proxy.
The Visual Studio solution
The source code provided here has been developed using Visual Studio 2010 and requires the following components be installed:
- Visual Studio 2010 Express Edition
- Entity Framework 4.0
- C# 4.0
- IIS 7
- SQL Server 2008 or 2008 Express
The following Visual Studio (C#) projects are included:
- SignInServices.Common: Includes common types
- SignInServices.CustomFederation: Is a sample Federation provider
- SignInServices: The Single Sign On WCF Service
- SSOClientServices: Includes a custom ASP.NET membership provider
- TestWebSite: An ASP.NET web site to test the SSO
How to download the source code?
The source code has been uploaded to CodePlex. Please go to http://wcfsso.codeplex.com and download the latest change set.
How to deploy?
In order to deploy the solution take the following actions:
- Restore the SQL Server 2008 Database in a SQL Server 2008 Server under the name of Framework
- Create a Windows login in SQL Server 2008 and grant access to the restored database (e.g. Domain\SSOUser).
- Launch IIS
- Create an application pool that works with .NET 4 and uses “Integrated” mode. Name this Application Pool as SSO.
- Set the identity account of the newly created application pool. This account must be equal to the Windows account that you added to SQL Server (e.g. Domain\SSOUser). This is required because the existing custom federation project is using Windows Authentication to access database.
- Open the solution file in Visual Studio 2010
- Publish SignInServices application to a folder
- Go to the folder
Open web.config file and configure the following entries:
- Under <appSettings> set SessionTimeOutMinutes. This value indicates that how long a sign-in ticket is valid.
- Under <appSettings> set federationType to any other federation type that you may want to use. If you want to use the custom federation type shipped with this sample, leave the current value as is.
- Under <connectionStrings> update the connection strings either if you have restored the database under any name other than “Framework” or you want to use SQL Server authentication rather Windows authentication.
- Build SignInService.CustomFederation project and copy the .DLL file to the \BIN folder of SignInService
- Build SSOClientServices project and copy the .DLL file to the \BIN folder of SignInService
- Go back to IIS
- Under IIS create a new Web Application that uses SSO as its Application Pool and points to the folder to which you published the SignInService application.
- Publish TestWebSite to IIS or simply run it in VS 2010.
Configuring the custom federation
The custom federation uses SMTP to send a new password to users once a password is requested to reset. The configuration of SMTP server is in Web.Config file of the WCF application (SignInSerivice). You must configure SMTP in order to reset passwords.
password=“password of sender“
Important notice: The solution file uses a custom database to store the user information. To add new users, simply install the SignInService under IIS and then navigate to http://service-url/Admin/ManageUsers.aspx for example if the SSO WCF service is deployed to http://127.0.0.1 /SSO/SSO.SVC, you may access the user management page via http://127.0.0.1/SSO/SSO.SVC/Admin/ManageUsers.aspx
(the admin page must be completed as I focused on developing the SSO service rather than implementing the admin web site)
Important notice: None of the applications or the WCF service is protected for simplicity purposes. If you deploy this solution to a production environment, you must protect them using ASP.NET authentication or WCF security practices.
Important notice: Once you launch the TestWebSite, you’ll see a login screen. Enter the following default credential to enter: