Apply Single-Sign-On to your application

Related Articles

Brief

In this ever-evolving world of technology, applications are getting more complex by the day but the economies of scale is not there when business users want them up to market faster and place great emphasis on ease of use.

The concept of Distributed computing has been around for almost a decade. However, distributed computing has mainly been confined within the walls of the organization and most importantly, vendor-specific platforms.

In the recent years, professional bodies came together and worked together with all the major platform vendors out there and came up with widely-accepted standards. Suddenly, platforms are not a major hindrance to communication anymore. The current explosion of bandwidth supply, coupled with the lower cost of utilizing it, plus other reasons, has also caused blurring of lines and boundaries between Local Area Network (LAN) and the Wide-Area Network (WAN). We are now seeing evolution of technology where a single application can span across multiple platforms and transcend physical barriers, parameters and boundaries.

While I don't want to go into details of what was described above, the topic of my article will touch one aspect of application development which I believe makes some sense to be farmed out to distributed computing and that is Identity Management.

Businesses of today are getting more difficult and complex and span across to other business domains as well. Software Vendors are finding it difficult to meet the requirements as the ways to do business are changing all the time as well. A full enterprise-resource planning suite is hard to built without third party involvement in terms of tools and support. After that, enterprises will demand that what is being deployed must work seamlessly with the other incumbent or new applications. One problem of that is the entry point of an application --- the Sign-on / Log-on Interface. If an enterprise should deploy a portal for the users to choose and use whichever application the need desires, the question is who holds the user indentity. If application A holds the main key to the user database, how would application B and C communicate with it seamlessly. Of course, with the use of widely-adopted web services and XML, the next question would be are Application A, B and C built in a way where identity management is loosely-coupled in their application architecture ? If so, who should hold the key, what are to be kept in this database and very importantly, who manages it ?

Ideal

One of the way I am recommending here is the use of the organizational directory. One of the key differences between a directory and a database is the frequency of the usage and of the data and also the rate of change. A Directory is very much like the Yellow Pages. You don't refer to it every minute or second of the day (frequency of usage) and it gets published only once a year (rate of change). All basic essential User identity is being stored in a company's directory within the IT Infrastructure. This can be in a IBM or Unix Mainframes, Novell Servers or Windows Active Directory. What is needed is a way to query and lookup the indexes of these directories to find the user and authenticate them. This is achieved by a common, widely-adopted and widely-accepted standard called Lightweight Directory Access Protocol (LDAP). Just like how Structured Query Language (SQL) queries databases, LDAP is used to query directories to return certain information.

In more ways than you think, it doesnt make sense for an application to hold another set of user data where the host platform of the application already holds a copy. The LDAP Directory is managed, rightfully, by the System Owner and he / she will also rightfully assign the proper rights to the different roles each application requires. Each user is authenticated just once with their user-credentials at logon time. From then on, their user-session is mapped onto their user-credentials, policies and authorization.

Launching an application will involve retrieving their current user session details and then querying the LDAP Directory for their user-roles and rights with that information. This is all transparent to the user and once the user gets authenticated and authorized by the LDAP Query, he/she will have access to all or portions of the application, depending on the roles of the user. Once that happens, Single-Sign-On is achieved.

Critics

Of course, the concept of Single-Sign-On in Identity Management has its critics. The most important flaw is that once a user signs-on at point of entry, he / she is signed-on as long as he / she is in the company's domain. Theorectically speaking, if he / she doesn't logged-off his / her machine, the session will always be authenticated regardless of who uses the same session later. In other words, while the user identity is not compromised, the current user session can be hijacked. This can easily happen when the user leaves his / her machine unattended and another person takes over the computer and the session. The main criteria of Single-Sign-On is that the user will only need to sign-on once (as the name suggests) and therefore, there should not be a logout button. Having one serves no purpose as it is the session that is authenticated, not the user anymore. The user only serves to create a valid session. If there is a login after a logout, then the rule of Single-Sign-On is flouted.

Another flaw of it includes the authentication of the user when the user is coming in from across domain. This will likely if he or she uses the same application via a Internet Interface with the same application sitting on the office domains. The user can be in their own personal own domain from home or elsewhere or using another person's machine, then their own personal user-credentials will be different from the one that is stored in the organization's domain. This will require users to do multiple logins which goes against the concepts of Single-Sign-On.

Some of the flaws can be solved by user-education. Educate the users to protect their machines whenever they are not around by locking up their sessions with a password-protected screen-saver or by other similar means. As of the second flaw, until a accepted secure and accepted tunelling protocol follows the user wherever he or she goes, that ideal may still be a way away.

Benefits

However, the benefits are heavy. User-rights, coupled with user and company policies are all centralized in a single place within the organization directory. Users have only one identity (userIds and Passwords) to maintain. Business owners will have the peace of mind that all entry points to applications and data are kept within a secure LDAP Directory with the company's user policy, password-policy in mind. This should be dictated by the business owners not by the software vendors. Different applications will all query one single user directory for their own authentication and should they require more application-specific data and field, redirect the user to collect more specific information from them. The storing of other information will ultimately be mapped onto the user common name in the LDAP Directory.

Solution(s)

Therefore, the best for now would be a hybrid of both scenarios, taking the pros and cons of both. Have an application architecture with a single user repository at the Organization's LDAP Directory but letting users sign on again for added security with the same user-credentials. This may solve the problem at hand. Still the ideal is to be and can be achieved. Imagine your client email application asking you for your password each time its goes out to receive or send your emails.

Microsoft .NET has made it easy to do both with just some switches of commands at a configuration file. Therefore, it doesnt take much to deploy either solutions depending on client needs.

I will dive into some VB.NET Coding to explain how both can be achieved.

Scenario A : True-Blue Single-Sign-On

1) At launch of application, query LDAP and see if the user is in the proper user-groups to access the application. I am, of course, assuming that groups are assigned to application, not individuals.

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim p As WindowsPrincipal = Thread.CurrentPrincipal
Dim a As New LDAPQuery
Dim objCook As New HttpCookie("LDAPCookie")
'Check for authentication and write into Cookie
Dim sLDAPCN As String = (a.GetCNByLDAP(p.Identity.Name))
'Check for LDAP Authentication First
If sLDAPCN <> "" And _
(a.blnFindCNinGroups(a.GetCNByLDAP(p.Identity.Name), "AppAUserGroups")) Then
objCook.Value = (sLDAPCN)
Response.Cookies.Add(objCook)
'Check for LDAP User Existence in Application Database
'If User exists in Application DB, Start Application

If (FindLDAPCNinDB(sLDAPCN)) Then
'DROP Authentication Cookie token
'Compute a hashed value of the current session ID
'into a cookie to signal authentication success
'Be sure to check for this cookie for every page load
'if value doesnt match or cookie doesnt exists,
'Re-do the whole authentication process again.
'Single-sign-on should continue, the cookies drop
'prevent authenticated LDAP Users from not having
'their CN mapped with other application-specific
'fields or data.

Response.Redirect("Welcome.aspx")
Else 'If False, do Database mapping
Response.Redirect("CollectOtherInfo.aspx")
End If
Else
Response.Redirect("LoginError.htm")
End If
End Sub


Private Function FindLDAPCNinDB(ByVal sLDAPCN As String) As Boolean
'For ease of setup, I am using a Flat XML File as a database
'However, a proper way would be to use a relational database
'You may use the ADO.NET to query and get information from the databse

Dim xmldoc As New XmlDocument
Dim xmlnode As XmlNode
Dim xmlnodelist As XmlNodeList
xmldoc.Load("D:WebDeployLDAPQueryFlatDB.xml")
xmlnodelist = xmldoc.SelectNodes("/Users/User")
For Each xmlnode In xmlnodelist
'Find LDAPCN
If xmlnode.ChildNodes.Item(0).InnerText = sLDAPCN Then
Return True
End If
Next
Return False
End Function
'###########
'###########

Imports System.DirectoryServices
Public Class LDAPQuery
'This function returns the Common Name (CN) of the Login information of the
'LDAP Directory. The CN is an unique identity and cannot be changed or edited in LDAP

Public Function GetCNByLDAP(ByVal strLogin As String) As String
Dim str As String = ""
'Parse the string to check if domain name is present.
Dim idx As Integer = strLogin.IndexOf("")
If (idx = -1) Then
idx = strLogin.IndexOf("@")
End If
Dim strDomain As String
Dim strName As String
If (idx <> -1) Then
strDomain = strLogin.Substring(0, idx)
strName = strLogin.Substring(idx + 1)
Else
strDomain = Environment.MachineName
strName = strLogin
End If
Dim obDirEntry As DirectoryEntry = Nothing
Try
Dim strPath As String = "LDAP://DC=Softwaremaker,DC=net"
obDirEntry = New DirectoryEntry(strPath)
Dim rootSearch As New DirectorySearcher(obDirEntry)
Dim SearchResult As SearchResult
Dim spn As String = strName & "@" & strDomain
rootSearch.Filter = ("(&(objectCategory=user)(userPrincipalName=" & spn & "))")
For Each SearchResult In rootSearch.FindAll 'Or FindOne
Dim i As Integer
'Check here - Should only return ONE result
For i = 0 To SearchResult.Properties("cn").Count - 1
str += SearchResult.Properties("cn")(i)
Next
Next
Catch ex As Exception
str = ex.Message
End Try
Return str
End Function


'Function finds and returns if User if in the specified user group
Public Function blnFindCNinGroups(ByVal sLogonUserCN As String, ByVal sGroup As String) As Boolean
Try
Dim sDirEnt As String = "LDAP://server/CN= " & sLogonUserCN&",CN=Users,DC=Softwaremaker,DC=net"
Dim user As DirectoryEntry = New DirectoryEntry(sDirEnt)
Dim pcoll As PropertyCollection = user.Properties
Dim i As Integer
Dim s As String
'The loop will return all Groups of which the CN is a member Of
For i = 0 To pcoll("memberOf").Count - 1
s = pcoll("memberOf")(i).ToString
If QueryLDAP(s, sGroup) = True Then Return True
Next
Return False
Catch ex As Exception
Return False
End Try
End Function


Public Function QueryLDAP(ByVal strQuery As String, ByVal sGroup As String) As Boolean
Dim obDirEntry As DirectoryEntry = Nothing
Try
Dim strPath As String = "LDAP://" & strQuery
Dim s As String
obDirEntry = New DirectoryEntry(strPath)
Dim rootSearch As New DirectorySearcher(obDirEntry)
Dim SearchResult As SearchResult
For Each SearchResult In rootSearch.FindAll
Dim i As Integer
'Check here - Should only return ONE result
For i = 0 To SearchResult.Properties("cn").Count - 1
s += SearchResult.Properties("cn")(i)
Next
If s = sGroup Then Return True
Next
Catch ex As Exception
Return False
End Try
End Function
End Class
'###########

2) I am not a LDAP Query guru or expert. I am sure I am taking one step too many just to query if the user exists within the specified user group in the LDAP Directory. But I am selling idea not code so you should get the idea :)
3) Things that can be applied includes :
a) Using Windows Authentication in the IIS Settings
b) At the web.config file level
'###########
<identity impersonate="true" /> <authentication mode="Windows" /> <authorization> <allow roles="SoftwaremakerNetAppAUserGroup" /> </authorization>
'###########

Scenario B : Hybrid Forms Authentication with LDAP

Please see the Microsoft link below for a detailed working version.
http://support.microsoft.com/default.aspx?scid=kb;EN-US;326340

Conclusion

The above examples only show the code implementations on the Microsoft .NET Platform. You can implement the same ideas with J2EE. As long as you built LDAP Capability into your application, it will work.

I hope you are able to see how you can integrate user identity management of a organizational directory into your application and map them onto your own databases. The users will still exist in the database but the management of their identity should be centralized within a LDAP Directory implementing companies policies and securities. There are a couple of ways that True-Blue Single-Sign-On can be applied across multiple domains. However, these implement rather new and expensive technologies such as physical authentication tokens which acts like your fingerprints. I will leave that topic for furthur discussions later.


Publication Date: Thursday 18th September, 2003
Author: Williamt View profile

Related Articles