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:
<appSettings>
<add
key=“federationType“
value=“SignInServices.CustomFederation.SSOCustomFederation,SignInServices.CustomFederation“/>
</appSettings>
This type is instanciated by reflection and provided to the consumers by SSOFederationHelper.FederationObject property. For example:
public
List<AuthenticatedUser>
FindUsersByEmail(string
EmailAddress)
{
return
SSOFederationHelper.FederationObject.FindUsersByEmail(EmailAddress).ToList();
}
- 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:
<authentication
mode=“Forms“ >
<forms
loginUrl=“~/Account/Login.aspx“
timeout=“2880” name=“.SSOV1Auth“ />
</authentication>
<authorization>
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:
<membership
defaultProvider=“SSOMembershipProvider“>
<providers>
<clear/>
<add
name=“SSOMembershipProvider“
type=“SSOClientServices.SSOMembershipProvider,SSOClientServices“
endPointUri=“http://localhost/SSO/service/sso.svc“
enablePasswordRetrieval=“false“
enablePasswordReset=“true“
requiresQuestionAndAnswer=“false“
requiresUniqueEmail=“false“
/>
</providers>
</membership>
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
- WCF
- 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.
<system.net>
<mailSettings>
<smtp
deliveryMethod=“Network“
from=“name@domain.com“>
<network
host=“smtp.mail.com“
userName=“name@domain.com“
password=“password of sender“
port=“25“ />
</smtp>
</mailSettings>
</system.net>
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:
User: aref.karimi
Password: 123

good works, thanks. I will try it ASAP.
Hi Elham
Please wait for a short time until the CodePlex project is activated (source code is hosted by codeplex.com)
i didn’t see any database script?
There is no script file. There is a SQL Server 2008 backup file.
i don’t believe you can run this under IIS 5.1 ?? Can you?
should not be a problem. as long as .NET 4 is installed on IIS
Nice article.. Can u please tell how to use this for Active directory auth?
sorry for the late reply. to use with Active directory you can write a Federation class and authenticate uses against active directory. Active Directory functionality is encapsulated in System.NET.
can i use this for [vc++ 6] Desktop client?.
you can use it for any kind of application that supports web services. you just need to call the web services explained.
Hi Gopal
I believe that roles are defined within the scope of one system/application. That’s why I did not include it in this article. However if you look at the documentation of Claim Based Authentication, it will help you to implement access right management.
How to use it in desktop client or mobile , I mean sso.
You can simulate the cookie thing for desktop apps.
You say that all the ASP.NET applications that take advantage of SSO service must give a same name to the Asp.net membership cookie. I want to know if they must also be in the same domain?
Seems that I have not expressed myself properly. I said if you give same cookine name to your ASP.NET applications (as well as same application name), they will use same ticket for authentication so you will have a kind of SSO! It’s not a robust way but is very simple to implement.
If you use the approach that I’ve mentioned, and also use a provider such as the one that I’ve provided, the applications will all use the same web service so they will work in a SSO fashion
What i want to know is. If i had 2 aplications:
http://www.domain1.com
http://www.domain2.com
and they are in diferent servers. can i use that sso?
Thanks for your fast answer.
Yes you can as the users will be stored in a single repository and a single shared service will perform the log-in and issue the authentication tokens.
I can not restore Framework.bak on to SQL Server 2008 R2 edition.
I am getting the following error.
TITLE: Microsoft SQL Server Management Studio
———————————————————
An exception occurred while executing a Transact-SQL statement or batch. (Microsoft.SqlServer.ConnectionInfo)
——————————
ADDITIONAL INFORMATION:
The media family on device ‘D:\Framework.bak’ is incorrectly formed. SQL Server cannot process this media family.
RESTORE HEADERONLY is terminating abnormally. (Microsoft SQL Server, Error: 3241)
Sorry for the late reply. I think the .BAK file is corrupt so maybe you should download and restore it again.
Thanks for the nice work. I got the database, since I am getting an error to restore from .bak file included, I generated from model to db and able to run the code successfully.