Click here to Skip to main content
Click here to Skip to main content

Tagged as

Go to top

Basics of Single Sign on (SSO)

, 23 May 2013
Rate this:
Please Sign up or sign in to vote.
SSO: Single sign-on (SSO)is a session/user authentication process that permits a user to enter one name and password in order to access multiple applications.

SSO: Single sign-on (SSO)is a session/user authentication process that permits a user to enter one name and password in order to access multiple applications. The process authenticates the user for all the applications they have been given rights to and eliminates further prompts when they switch applications.

When I looked at a SSO infrastructure, one thing i understood is, "It is very secure in execution and very complex to understand in first look". So, with the knowledge i acquired through various sources, i decided to create a small POC demonstrating what we have in SSO and how it works, starting from very basics.

Typically SSO comes into the picture when there is a user switching between different application domains.

Example: we are working in IT companies, and basically IT companies wont take burden of payroll and insurance process. So they will hire a vendor to take care of these activities. In that case there will be a links to those sites in your company sites. If you observe the Urls, they are of different domains (http://xxxxx.com). But when you navigate from your company site to vendor site, it will not ask for UserId and password.

Does this mean UserId and Password for both the sites are same?

No, In most of the real time scenarios, they will be different. Now we have a question how this authentication is taken care? Ans: One of the Answers is SSO.

Lets demonstrate and verify its functionality step by step.

Step 1: Create an forms authentication application "Main Application", representing our company site.

Why Forms Authentication, why not Windows authentication? 

You can use Any one. But ultimately the SSO works on claims based authentication irrespective of what authentication you use in your application. My MainApp (SSOBase1) has a MainLogin page and a MainApppage.

Step 2: Create a second Forms application which can represent a Vendor or Client application.

Step 3: In order to accommodate forms authentication we need to have a database to maintain credentials. So create a DB supporting infrastructure for your application. In real time scenarios, you will have different databases for both the applications. But for simplicity i created a single database but maintained this isolation in application. Lets see how.

Database:

 Main App DBML:

 Client App DBML:

Now observe the dbml files care fully. Main app deals nothing with Client1 application DB tables and viseversa. So we are maintaining complete isolation between DB infrastructure of Main app and client apps.

Main app / STS DB will have following information:

  1. User credentials for Main application.
  2. List of Client / Vendor apps serving our Main Application.
  3. Which user and their accessibility to Client / Vendor application.

Client App DB will have following Information:

  1. Client Application credentials.
  2. Mapping between STS Security Token or Claim and the Client application credentials.

Step 4: Now implement respective Forms authentication so that no unauthenticated users can enter individual apps.

Main app:

Client App 1:

Look at the Urls carefully. You can see the applications are redirecting Unauthenticated user to respective Login pages for authentication.

Step 5: Now coming to user switching between cross domain applications. SSO uses a authentication provider typically called as STS (Secure Token System).

STS: This is the system which will authenticate the user and its authentication will be trusted by all the parties both Main application and Vendor/Client applications. Once a user has been authenticated by STS, all the client applications served by this STS will trust the user and no further authentication should be prompted.

STS can be part of Main App or a Individual service or App.

Now lets see how we have handled this in our application. if you observe clearly the snapshot of Main app, we have a web service "Authenticator.asmx".

This acts like a STS system and usually takes the responsibilities:

  1. Authenticating users
  2. Verifying what all applications he is authorized to.
  3. Providing specific Security Token or Claims (Pieces of information which client app will agree as Authentication)

Look at the different methods:

  • Authenticator(): Constructor accepting logged in userId.
  • AuthenticateUser(): Method which will verify the user authentication for Main App.
  • GetAppAccessDetails(): This method will collect information of all client or vendor sites for which current user is authenticated, from STS / Main App's DB.
  • AuthenticateClientUrl(): This method will provide required security token or claims required by Vendor / Client application.

Step 6: Only changes a vendor system has to do is, while logging it have to look out whether user is authenticated by STS or not. If yes, allow him to Client HomePage. If no Redirect him to Login page of Client Application. In order to implement this, i added a query string with name "IsAuthenticatedBySSO", while redirecting to client application. This action is been taken care by  AuthenticateClientUrl() method of STS. Just follow the below pieces of code from both STS and Client home page.

STS

namespace SSOBase1
{    
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    
    public class Authenticator : System.Web.Services.WebService
    {
        string _userId;
        public Authenticator(string UserId)
        {
            _userId = UserId;
        }

        [WebMethod]
        public bool AuthenticateUser(string password)
        {            
            SSODBDataContext db = new SSODBDataContext();
            var psw = (from c in db.MainAppCredentials
                      where c.Userid == _userId
                      select c.Password).ToList();
            string strPsw = psw[0].ToString();
            return strPsw == password ? true : false;                    
        }

        [WebMethod]
        public DataTable GetAppAccessDetails()
        {
            SSODBDataContext db = new SSODBDataContext();
            var results=(from a in db.Apps
                             join ua in db.UserAppMaps on a.AppId equals ua.AppId
                             where ua.MUserId == _userId
                             select a).ToList();
            
            DataTable dtRes=new DataTable();
            dtRes.Columns.Add("ApplicationName");        
            dtRes.Columns.Add("ApplicationURL");
            foreach(var c in results)
            {
                DataRow dr=dtRes.NewRow();
                dr[0]=c.AppName;
                dr[1]=c.AppUrl;
                dtRes.Rows.Add(dr);
            }
            return dtRes;
        }

        [WebMethod]
        public string AuthenticateClientUrl(string clientUrl)
        {
            return clientUrl + "?UserId=" + _userId + 
                     "&IsAuthenticatedBySSO=1";
        }

    }
}

Client Home Page

namespace SSOTestClientApp1
{
    public partial class Client1MainPage : System.Web.UI.Page
    {
        string struser;
        protected void Page_Load(object sender, EventArgs e)
        {
            if (Request.QueryString["UserId"] == null && 
                      Session["FromClient1Login"] == null)
                FormsAuthentication.RedirectToLoginPage();
            else
            {
                if (Session["FromClient1Login"] != null)
                {
                    struser = Session["Userid"].ToString();
                    lblMessage.Text = "Welcome " + struser + 
                      System.Environment.NewLine + " This Login is from Client 1 login";
                }
                else if (Request.QueryString["IsAuthenticatedBySSO"].ToString()== "1")
                {
                    struser = Request.QueryString["UserId"].ToString();
                    SSOClient1DBDataContext db = new SSOClient1DBDataContext();
                    var _appSpecificUserName = (from u in db.Client1Maps
                                                where u.MainAppUserId == struser
                                                select u.C1AppUserId).ToList();
                    struser = _appSpecificUserName[0].ToString();
                    lblMessage.Text = "Welcome " + struser + 
                      System.Environment.NewLine + " This Login is from SSO";
                }
            }
        }
    }
}

In client home page:

  1. The first highlighted part will verify if user is authenticated by either Client1 Login page nor STS. If yes, it will redirect user to Client1 Application login page.
  2. The second highlighted part will display message when user is authenticated from Vendor or Client login page directly.
  3. The third one will display message when user is been authenticated by STS.

Step 7:Now, lets hit the Vendor Main Page.

lets log in with Vendor credentials.

Now Hit Main Application.

Enter Main application.

Now How this Hyperlinks appear on Main application home page. Look at the code below:

namespace SSOBase1
{
    public partial class MainAppPage : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (Session["UserId"] == null)                
                FormsAuthentication.RedirectToLoginPage();
            else
            {

                string _userId = Session["UserId"].ToString();
                lblMessage.Text = "Welcome " + _userId + " to Main Application.";
                Authenticator svc = new Authenticator(_userId);
                DataTable dtResult = svc.GetAppAccessDetails();
                foreach (DataRow dr in dtResult.Rows)
                {
                    HyperLink _hyperlink = new HyperLink();
                    _hyperlink.Text = dr["ApplicationName"].ToString();
                    _hyperlink.NavigateUrl = svc.AuthenticateClientUrl(dr["ApplicationURL"].ToString());
                    divLinks.Controls.Add(_hyperlink);
                    divLinks.Controls.Add(new LiteralControl("<BR>"));
                }
            }
        }
    }
}

Now Click on Client1 Link:

Look at the message and cross check with the Client Home page code, you will see how the LoginUser mapping is done and how the Client application has accepted the token provided by STS.

But I pick up Query string for security token, some one may pick up some thing else. So SSO has standardized the token approach by taking SAML (Security Assertion Markup Language). We will discuss all the standards and the real time implementation in next post.

Now we clearly understood the basic skeleton behind SSO.
Code: Click Here and download SSOBase1
Is it helpful for you? Kindly let me know your comments / questions.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author


Comments and Discussions

 
BugBe careful with this code. PinmemberDarren Weir24-Aug-14 19:36 
QuestionMessage Removed PinmemberMember 1074953923-Jun-14 19:40 
Questiongood ideas PinmemberMember 812069721-Apr-14 16:25 
QuestionSource code PinmemberMuhammad Mobeen Qureshi27-Feb-14 1:53 
AnswerRe: Source code PinmemberPratapReddyP2-Mar-14 10:46 
AnswerRe: Source code PinmemberVishal Patel2-Mar-14 18:04 
QuestionCan we do this in MVC 4.5? Please advise PinmemberMember 103602106-Jan-14 9:47 
QuestionConfiguring SSO client app to authenticate Pinmemberbmuhammad20-Dec-13 12:05 
AnswerRe: Configuring SSO client app to authenticate PinmemberPratapReddyP14-Jan-14 12:45 
QuestionBasics of Single Sign on (SSO) [modified] PinmemberMember 12363418-Nov-13 5:51 
QuestionSigle sign on [modified] Pinmemberdudu4353-Oct-13 3:52 
QuestionDatabase tables PinmemberMember 288681529-Jun-13 15:06 
QuestionRe: Database tables Pinmemberbuaaytt31-Aug-13 18:28 
AnswerRe: Database tables Pinmemberderfrent3-Sep-13 10:07 
GeneralRe: Database tables PinmemberPratapReddyP8-Sep-13 0:01 
GeneralRe: Database tables PinmemberRightSideOfWrong14-Mar-14 23:41 
QuestionSSO PinmemberMember 288681529-Jun-13 14:44 
GeneralMy vote of 4 Pinmembermrwisdom23-May-13 21:17 
QuestionSource Code Pinmemberkaushik baidya22-May-13 7:52 
AnswerRe: Source Code PinmemberPratapReddyP22-May-13 8:56 
QuestionExample code PinmemberAbu Yusuff Alkalantani19-May-13 17:44 
AnswerRe: Example code PinmemberPratapReddyP20-May-13 18:54 
QuestionSTS Service Pinmembershouha8517-Feb-13 21:55 
Questioncan I have your source code PinmemberMapGuy1113-Feb-13 10:04 
AnswerRe: can I have your source code PinmemberPratapReddyP20-May-13 18:54 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140916.1 | Last Updated 23 May 2013
Article Copyright 2012 by PratapReddyP
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid