Enable Single Sign-on in ASP.NET with Passport

he first article of this series, “Set Up Passport Authentication in ASP.NET“, discussed using the authentication features of Microsoft Passport in ASP.NET applications. This second and final installment demonstrates how to use the same authentication features to enable single sign-on (SSO). SSO enables users to authenticate themselves at one site and then use the resources of several trusted sites without re-authentication.

To provide an understanding of the SSO process, the article first explains the features that comprise single sign-on. The second section details the data formats Passport uses, as well as the information exchange during SSO. The next section puts the pieces together and demonstrates the actual SSO process. The final section describes how to fulfill the sign-out requirements of Passport authentication.

Single Sign-on Features
The following subsections describe the features that SSO enables in participant sites and applications.

Using the Same Authentication Token on Multiple SSO-enabled Sites
E-commerce site users can use the same authentication token on multiple SSO-enabled sites. Authentication tokens identify the site user. The login/password pair is one type of authentication token, the digital certificate is another.

Microsoft Passport uses keys and encryption for its authentication. Microsoft Passport server issues a private key to every Passport-enabled application and stores the matching public key in its database. It uses the public key to encrypt the Passport ticket (which contains the user authentication data) being sent to the Passport-enabled application. The PassportIdentity class (also called the Passport Manager) automatically decrypts the Passport ticket using the private key. This way, the Passport Server ensures that the authentication data remains confidential while traveling over the Internet.

Sharing Authentication Process Overhead
SSO also enables different Web applications to share authentication process overhead. This means one application, which has authenticated a user, can share that authentication information with other trusted applications.

This sharing of authentication information is useful only if the different applications trust the authentication process. Therefore, SSO is usually applicable only within a trusted domain. If you didn’t trust the authentication process that Microsoft Passport server performs, you wouldn’t Passport-enable your site and therefore wouldn’t be part of the trusted Passport domain.

Such a trusted domain may or may not cross the boundaries of an enterprise. For example, different applications running within the same enterprise may share authentication information. The enterprise therefore serves as a trusted domain for all the applications. Another example of trusted domains is an electronic marketplace.

Enforcing Their Own Authorization Policies
Authorization (allowing an authenticated user to use a particular resource or service) is based on company polices. Microsoft Passport allows Passport-enabled applications to see some profile information of authenticated users, such as name, occupation, country of origin, etc. A Passport-enabled application can use the profile information to implement its own authorization polices. Therefore, you can use Passport as an authentication mechanism to allow your site users to login and then, once they’re logged in, grant them privileges according to your own authorization policies.

Handing Sign-out Logic
Just like authorization polices, SSO also allows a participant site to handle sign-out logic. When a user signs out, the Passport server calls the sign-out page of all Passport-enabled applications to which the user was authenticated during his or her current sign-in session. It is up to the Passport-enabled applications to handle their own sign-out logic. (The “The Passport Sign-out Procedure” section of this article examines the sign-out details.)

Data Formats and Information Flow in Passport-based SSO
To fully demystify the Passport technology, this section discusses the data formats used during Passport-based authentication. The authentication information flows over the Internet in the form of HTTP URLs. This section lists all the URLs and explains which information they carry. (Refer back to Figure 1 and the explanation of each authentication step in “Set Up Passport Authentication in ASP.NET.”)

URL That Identifies Passport-enabled Applications
The first URL involved in the Passport process is the URL that identifies Passport-enabled applications (for example, http://www.MyPassportEnabledApplication.com, a fictitious URL). The user enters this URL in his or her browser and starts browsing. In the previous article, I instantiated a PassportIdentity object and then called its LogoTag2 method. The LogoTag2 method of the PassportIdentity object in a Passport-enabled application checks whether the request from the user contains any authentication information. If no authentication information accompanies the request, the LogoTag2 method serves a sign-in button in response.

For example, because the example URL in the previous paragraph does not contain any authentication data, the LogoTag2 method in a Passport-enabled application would serve the sign-in button in response to it. Figure 1 (a screen shot of a fictitious tour operator) shows how the sign-in button looks. (The ASP.NET page for this application is included in the code download for this article.)

Click to enlarge
Figure 1: A Web Page with a Sign-in Button

The code for the Figure 1 sign-in button looks something like this:

     Sign in with your Passport.

The HREF attribute of the tag points to a target URL address (www.MyPassportEnabledApplication.com/ along with some parameter-value pairs), while the tag points to the source of the sign-in button image. When the user presses the sign-in button, his or her browser visits the target URL (which is the value of the HREF attribute of the tag):

http://www.MyPassportEnabledApplication.com?msppchlg=1&
mspplogin=http://current-login.passporttest.com/login.srf?lc=1033&id=32842&
ru=www.MyPassportEnabledApplication.com&tw=900&kv=1&ct=1040030836&
ns=localhost&ver=2.1.0191.1&tpf=594cb4b7134ac2b6c4b9d71c0b9e6f8d

This URL is the same as the example Passport-enabled application (http://www.MyPassportEnabledApplication.com), along with some parameters. So pressing the sign-in button sends the parameters to the example Passport-enabled application.

URL for the Address of the Passport Login Site
When the PassportIdentity class in a Passport-enabled application sees the parameters described in
the sidebar coming from the browser, it redirects the user to another URL, as shown below:

http://current-login.passporttest.com/login.srf?lc=1033&id=32842

This URL is the address of the Passport login site, which serves the login page (see Figure 2).

Click to enlarge
Figure 2: The Login Page

The user enters his user name and password and presses the sign-in button. This time the app sends a secure HTTP request to the secure HTTP server that Microsoft hosts for Passport login. This secure channel maintains the confidentiality of the user’s password as it goes to the Passport server.Notice that the login page in Figure 2 has two check boxes: Sign me in automatically and I'm using a public computer. These boxes are the opposite of each other and checking one automatically unchecks the other. The boxes control whether the app stores authentication data in the user’s browser (as cookies). If the Sign me in automatically box is checked, the data is stored in the user’s browser. If the user is browsing from a public computer (e.g., in an Internet cafThe Single Sign-on Experience with Passport
This section demonstrates the SSO experience for Passport users and shows how a Passport-enabled application can control that experience. For this demonstration, I developed two sample Passport-enabled applications. The first application is a fictitious tour operator, and the second is a fictitious hotel. The source code download for this article includes both applications along with instructions for installing and running them.

Both the applications use the PassportIdentity class. The PassportIdentity objects in the two applications differ slightly, which will demonstrate the control you can have of the user experience according to the business logic of your Passport-enabled applications. The two applications also pass different values for the second and third parameters to the PassportIdentity.LogoTag2 method. The result is that one application requires more frequent re-authentication of the user than the other does.

I will elaborate on the difference between the PassportIdentity objects in the two applications shortly, but first I’ll demonstrate SSO using the two sample applications included in the source code download. I used the following sequence of operations to demonstrate SSO in the download files:

  1. I deployed the two applications independent of each other on two different IIS servers running on two different machines.
  2. Once the two applications were running, I opened a browser session and accessed the first application (the tour operator application). I received the page shown in Figure 1. I pressed the Sign-in button and received the login page shown in Figure 2.
  3. I entered a user name and password and checked the Sign me in automatically check box. Then I pressed the Sign-in button.
  4. I received the page shown in Figure 4, which is the successfully authenticated and logged in screen for the tour operator application.
    Click to enlarge
    Figure 4: Successfully Authenticated Page for Tour Operator Application
  5. I started another browser window and accessed the second application (the hotel application). I received the screen show in Figure 5. I pressed the Sign-in button and received the successfully authenticated and logged in screen shown in Figure 6. Notice I did not need to enter the user name and password this time, because the Sign-in process used my previously authenticated data for login.
    Click to enlarge
    Figure 5: The Hotel Application Showing a Sign-in Button
    Click to enlarge
    Figure 6: Successfully Authenticated Page for the Hotel Application

Why didn’t the hotel application ask for the user name and the password? How did it know that I am already authenticated? The tour operator application set the Passport ticket as a cookie in my browser. When I pressed the Sign-in button, the ticket was presented. The Passport server analyzed the ticket and found it to be a valid authentication token, so the Passport server authenticated me without first asking for the user name and password. After successful authentication, the Passport server re-directed me to the hotel application, which simply served the page shown in Figure 6.

Try the same procedure without clicking the Sign me in automatically check box. The Passport ticket will not be stored in the browser and therefore you will have to re-enter the authentication information each time you login to any Passport-enabled application.

In the real world, different Passport-enabled applications will have different user-authentication preferences. For example, a banking application may set a very short session time after which users will be required to re-authenticate. A vacation tour operator, on the other hand, may not need to implement such a strict security policy and may allow users long session times.

To demonstrate this, I used different values in the second and third parameters of the PassportIdentity.LogoTag2 method in each of the two sample projects. The following code shows the PassportIdentity.LogoTag2 method call in the tour operator applications:

passportId.LogoTag2( _    Page.Request.Url.ToString(),_    900, _    False, _    Nothing, _    1033, _    Page.Request.IsSecureConnection, _    Page.Request.ServerVariables("SERVER_NAME"), _    0, _    False))

The following listing shows how I used the PassportIdentity class in the hotel application:

passportId.LogoTag2( _    Page.Request.Url.ToString(), _    180, _    True, _    Nothing, _    1033, _    Page.Request.IsSecureConnection, _    Page.Request.ServerVariables("SERVER_NAME"), _    0, _    False))

Look at the PassportIdentity.Logotag2 method call in the tour operator application. Notice that the time window parameter value (the value of the second parameter) is set to 900 (i.e., time in seconds after which user authentication ticket will expire) and forced login (the third parameter) is set to ‘False’. In the hotel application , the time window value is set to ‘180’ and the forced login is set to ‘True’, which means the user will be forced to re-authenticate after the time window expires. Try these application settings to see the effect of the windows.

Try the following steps and observe interesting results:

  1. Access the tour operator application and get authenticated. After authentication, you’ll arrive at the page shown in Figure 4 (Don’t forget to check the “Sign me in automatically” box).
  2. Open a new browser window and access the hotel application. You will get the screen shown in Figure 5. Wait about three minutes, and then press the Sign-in button. You will get the screen shown in Figure 7, which requires your password. Enter your password and press the sign-in button. You will be authenticated.
    Click to enlarge
    Figure 7: Screen That Asks for the User’s Password

You might be wondering why you got the Figure 7 screen. The reason is simple. The hotel application has a time window of 180 seconds and forced login set to true. When you accessed the second application, the authentication ticket in the cookies set by the tour operator application was presented for re-authentication. The PassportIdentity object in the hotel application checked the time passed since the first authentication and found that the ticket is more then 180 seconds old. So you were re-directed to the Passport server for re-authentication.

What would have happened if the forced login was set to false? Try this yourself by authenticating first at the hotel application and then visiting the tour operator application. This time, you will not get a screen that asks for the password (Figure 7), even if you wait for more than 900 seconds (time window for the tour operator application). After the time window expires, the authentication ticket automatically refreshes for the tour operator application, because the forced login is set to false. So when you access the tour operator application, the authentication ticket previously created (at the time of signing into the hotel application) is accepted and re-authentication is not required.

The Passport Sign-out Procedure
The Microsoft Passport Server needs an expire cookies URL when creating a new Passport-enabled application. The expire cookies URL is the address that Passport server invokes when a user of this application presses the Sign-out button. When a user presses the Sign-out button on any Passport-enabled application, it generates the following URL:

http://current-login.passporttest.com/logout.srf?lc=1033&id=32842&
ru=http://www.MyPassportEnabledApplication.com/WebForm1.aspx&tw=900&kv=1&
ct=1042006727&ems=1&ver=2.1.0191.1&tpf=ad9ade4448ea55179462bd5a2fb3ca0b

As you can see, the URL points to the Microsoft Passport server. The Passport server keeps a record of all sites that a user signs -in during a login session. The logout page on the Passport server automatically detects all Passport-enabled applications that the user currently has signed in. Once the Passport server knows the list of all Passport-enabled applications that the user currently has signed in, it invokes the expire cookies URL of each of the Passport-enabled applications on the list.

The purpose of this logout procedure is for the Passport server to provide each Passport-enabled application an opportunity to take some action when a user signs out. It is up to the Passport-enabled application to decide which logout logic it needs. This is analogous to having object destructors in object-oriented programming languages like C++ and Java to implement cleanup logic when an object is deleted.

The simplest logout possibility (when you don’t want to do anything during logout) is to use the following code:

<%@ Page Language="vb" AutoEventWireup="false" Codebehind="ExpireCookies.aspx.vb" Inherits="MyPassportEnabledApplication.WebForm1"%><%	Response.ContentType = "image/gif"   	Response.Expires = -1	Response.AddHeader("P3P", "CP=TST") 	Response.WriteFile("signout_good.gif")%>

This code does nothing more than send a GIF image back to the Passport server. The image is normally a green check mark that indicates the user has been successfully signed out of the application. Look at the Response.WriteFile line in the above code. This line writes the signout_good.gif image on the response stream. Passport-enabled applications can download the standard green check mark image http://www.passportimages.com/1033/signout_good.gif before writing it to the response stream. Each Passport-enabled application to which the user was signed in will send one image. Microsoft Passport server will show the image next to the application on the successful sign out page (see Figure 8).

Click to enlarge
Figure 8: A Successfully Signed-out Page

Author Note: The code above includes a Response.AddHeader line, which adds a P3P header to the response stream. P3P (Platform for Privacy Preferences) is a W3C standard that expresses privacy policies. P3P-aware browsers like IE 6 require this header to allow deleting browser cookies. Refer to the official P3P page at http://www.w3.org/P3P/ for more details about P3P.

The successfully signed-out page shown in Figure 8 is displayed to the user for a few seconds after successful sign-out from all sites. The user is then redirected back to the original calling page where he or she pressed the Sign-out button.

The Passport server needs a GIF image returned in response to the expire cookies URL. If the page at expire cookies URL does not return an image or sends something else in response, the Passport server gets confused and puts a red mark against the Passport-enabled site’s name on the successfully logged-out page. Figure 9 shows this mark where the Passport-enabled application failed to return a GIF image in response to the logout URL.

Click to enlarge
Figure 9: A Page Showing Sign-out Failure

This image is the only requisite of the Passport server. You are free to do other processing (e.g., destruction of server-side session objects on logout) in addition to serving the image back to the Passport server. However, remember that the response from the expire cookies URL should contain only the GIF image. Whatever server-side sign-out processing you want to perform, your Expire Cookie page should not write anything else on the response stream.

Notice one last thing about signing out of Passport-enabled sites. If you don’t check the Sign me in automatically box while signing in, then you will have to sign out of all the Passport-enabled sites individually. You can verify this option by logging into several Passport sites without clicking the “Sign-me automatically” button and then trying to sign out.

What Have We Learned?
This article demonstrated the use of Passport for SSO applications. It started by explaining the features that are collectively known as SSO. It then explained the flow of information that occurs when a user logs on to a Passport-enabled application. The next section demonstrated the actual SSO and explained how different Passport-enabled applications can customize the user’s SSO experience according to the unique requirements of a particular Passport application. The last section explained the sign-out logic in Passport-enabled applications.

Share the Post:
Share on facebook
Share on twitter
Share on linkedin

Overview

Recent Articles: