Authenticate Users with Microsoft Passport

Make User Logins Simple and Consistent

asp:feature

Languages: C# | VB

Technologies: Security | Authentication | Passport

 

Authenticate Users with Microsoft Passport

Make User Logins Simple and Consistent

 

By Steve Turley

 

Passport is the key technology used by .NET My Services to authenticate users on a Web site. Adding Passport to your ASP.NET site is easy to do and gives the user a consistent, convenient method of logging in without having to remember yet another user name and password. ASP.NET wraps much of the older Passport SDK to provide a single object and simple configuration.

 

Writing an ASP.NET site enabled with .NET Passport is relatively simple: You install the .NET Passport SDK, register your site, install your .NET Passport site key, change your s ite's authentication mode to Passport, and deny access to unauthorized users. (These last two items occur in the site's web.config file.) That's it. Your site now requires all users to sign in with their .NET Passport account before they can see any content. Follow along, and this article will show you how it's done.

 

The User's Experience

Imagine you have a site, www.mysite.com, with a home page named default.aspx. The site's virtual directory contains a web.config file enables Passport authentication and blocks any access to the site until the user has signed into his or her .NET Passport account:

 

    

        

            

        

        

            

        

    

 

For example, a user named John browses to your site. Because he hasn't signed into his .NET Passport account during this session, the first thing John sees is the screen shown in FIGURE 1.

 


FIGURE 1: This is the default page unauthorized users will see when trying to access the site without signing into their Passport account. However, you might wish to construct a more attractive and user-friendly page.

 

When clicking on the Sign In button, which those familiar with Passport refer to as a scarab, John sees the page shown in FIGURE 2.

 


FIGURE 2:  The Passport server provides the .NET Passport sign-in page. Passport validates the user's name and password and it returns a ticket to the client.

 

Now John enters his .NET Passport credentials. If he doesn't have a .NET Passport account, he can get one here. He also can access pages on the Microsoft .NET Passport site to learn more about .NET Passport. Once he enters his credentials, which consist of his e-mail address and password, John clicks on the Sign In button. Voil . He finally sees the page he originally requested, www.mysite.com/default.aspx. After he signs in, John can browse the site at his leisure. Moreover, he can browse to any .NET Passport site, even sites in completely separate domains, without signing in again. After he finishes, he signs out by clicking on the .NET Passport scarab again or simply closing his browser.

 

A .NET Passport site needs a few more things before it is considered a valid site that you can make public. The SDK help file offers a complete checklist. Look for the topic Reviewing the Checklist. One important requirement is that every site using .NET Passport displays the sign-in and sign-out scarab on every page. You'll see how to do this later, but for now, consider what's happening during John's visit to your site: John requests www.mysite.com/default.aspx. ASP.NET notices that unauthorized users are denied by virtue of entries in the web.config file:

 

 

ASP.NET notices the site uses Passport authentication and unauthenticated users are to be sent to the internal page for authentication:

 

 

ASP.NET automatically redirects the user to the built-in, internal authentication page. This is the first page John sees-the one that denies him access. This page doesn't authenticate John, but instead, it simply has a link (the scarab) to another page. Next, John clicks on the Passport sign-in scarab, which sends him to the .NET Passport sign-in page provided by the Microsoft .NET Passport servers. John signs in.

 

Now Passport authenticates John by comparing his sign-in information (e-mail address and password) with the information in its database. If John presents valid credentials, the Passport server sets some cookies on his browser and (finally) sends him to the page he originally wanted. This time, ASP.NET sees that John is authenticated (his browser has the Passport cookies) and lets him view the page. Once John's browser has the Passport cookies, he can visit any .NET Passport site without signing in again. For tighter security, sites can control automatic sign-in if they want by requiring, for example, that the user signs in within a certain time limit, and a site could also force John to sign in again even though he has valid credentials. In addition, John is able to delete the cookies at any time by signing out explicitly or by closing his browser.

 

Notice that during John's visit, the entire Web site is protected. Regardless of the page John requests, ASP.NET would stop him and require him to sign in. But, once signed in, he has free access to the entire site. Sometimes this is exactly what you want, but sometimes it isn't. Here are two easy ways to pick and choose which pages you want to protect: You could put all the protected pages in a separate directory and set the authentication and authorization requirements in it while leaving your main directory open to everyone; or you could use tags in your web.config to require authentication for specific pages only. But this gets cumbersome if you have many pages to protect.

 

Only ASP.NET (e.g.., aspx, asmx, ascx, and so on) pages are protected by web.config settings. HTML and ASP pages are not affected and are accessible to anyone.

 

Passport Identity

Every client that accesses your Web site has an Identity object associated with it. The Identity is available to your ASP.NET code as Context.User.Identity. Simple unauthenticated pages have a GenericIdentity, which provides a few properties such as Name, AuthenticationType, and IsAuthenticated. When Passport authentication is used, the page has a PassportIdentity, which is significantly more powerful. Among the most important differences is that the Name property is a unique, 16-digit, hexadecimal string that identifies the user. FIGURE 3 shows some of the interesting members of the PassportIdentity class (see the .NET Framework documentation for compete details).

 

Property or Method

Data Type

Comment

AuthenticationType

String property

"Passport"

Error

Property

Passport error code

GetFromNetworkServer

Boolean property

True when the client has just returned from signing in; otherwise False

HexPUID

String property (2.x SDK only)

The unique Passport User Identity (PUID) for this user

IsAuthenticated

Boolean property

True if the user is signed in

Name

String property

Same as HexPUID

TicketAge

Int property

Number of seconds since the user signed in

GetCurrentConfig

String method (2.x SDK only)

Returns configuration information from the registry

GetIsAuthenticated

Boolean method

Similar to IsAuthenticated property but allows testing for timeout

GetProfileObject

Method

Returns information from the user's profile

LogoTag2

Method

Displays the scarab

LoginUser

Method

Redirects user to sign-in server

FIGURE 3: This is a partial list of properties and methods the PassportIdentity object provides.

 

By using a page's PassportIdentity object, you can make your pages more useful and powerful. You must use a minimum set of its features to meet the Passport requirements before you can publish your site. For example, Passport requires you to display the sign-out scarab on every protected page. The LogoTag2 method does this for you.

 

Tactical Authentication

The Web site described at the beginning of this article uses hard authentication, so it's all or nothing. By using subdirectories or tags, you can control access to individual pages. But you might want even finer control of the protected areas. For example, imagine your site is accessible to everyone but offers additional or personalized content to authenticated users. MSN.com is a perfect example of this. Anyone can view it, but users who sign in have additional, personalized content and layout. Passport makes this level of control easy: Remove the section from your web.config file, then use the PassportIdentity.IsAuthenticated flag to control the portions of the page you want to customize. Use the .NET PUID to identify the user and look up details for personalizing the page.

 

In a basic example, the web.config file looks like this:

 

    

        

    

 

Notice that no one is denied access; anyone can view any page. It's up to each page to determine whether users are authenticated.

 

FIGURE 4 shows a simple page that displays the user's PUID and some special content if they sign in.

 

...

...

FIGURE 4: This excerpt from a simple Passport-enabled page uses the PassportIdentity's LogoTag2 method to display the scarab and the IsAuthenticated property to control the page's content.

 

The IsAuthenticated property is used to control the content and visibility of the content on the page. If the user is authenticated, the text of authLabel and authLabel2 is modified. The page also uses a panel server control to contain a block of material that is invisible to unauthenticated users.

 

The PUID is guaranteed to be unique for each user. The sample page in FIGURE 4 doesn't do much with it, but it's easy to see how you could use the PUID to provide an index into a database to obtain the user's preferences or other information you could use to further customize the page.

 

In the 2.x version of the Passport SDK, the PUID string is available as both the PassportIdentity.Name and PassportIdentity.HexPUID properties. In version 1.4, it is available from the user's profile as MemberIDHigh and MemberIDLow. To construct the full PUID, you need to combine them:

 

string PUID = String.Format("{0:X8}{1:X8}",

 id.GetProfileObject("MemberIdHigh"),

 id.GetProfileObject("MemberIdLow") );

 

The PUID also can fine-tune site access. Use it in the web.config file to allow or deny access to specific PUIDs:

 

    

        

            

            

        

    

 

For example, you might use this to make an administration page available only to a restricted set of users.

 

Put It All Together

If you're going to display the scarab and check authentication on each page, you will need to add code like that contained in FIGURE 4 to every page on your site. The obvious way to do this is to encapsulate it all in a user control and add the control to every page. Now, the sample page becomes what you see in FIGURE 5.

 

<%@ Register TagPrefix="passport" TagName="scarab"

 Src="Figure7_cs.ascx" %>

 

Simple PassportControl Page

 

 

Simple PassportControl Page

 

 

You are not authenticated. Please sign in with your

.NET Passport.


 

 visible="false">

This material is only visible to authenticated users.

 

FIGURE 5: You can simplify this page by encapsulating all the Passport code into a user control. Find the source code for the user control on the online version of this article.

 

When you register your site with Passport, you might have specified a Logout URL. This is the URL the user is sent to after signing out from Passport. Be sure this page doesn't require hard authentication. If it does, the user will sign out, only to be forced to sign in again to see the logout page - not a friendly design. You also will want to ensure that your co-branding material, privacy policy, terms of use, and customer-support pages are freely accessible.

 

Signing Out

When a user signs out of .NET Passport by clicking on the scarab in its sign-out mode, it is your site's responsibility to delete any cookies it created. The .NET Passport servers keep track of the sites the user visits and automatically request an expire-cookie page (also called the Logoutgif page) from each site when the user clicks on the sign-out scarab. You must provide this page on your site, and you provide its URL to .NET Passport when you register the site. ASP.NET provides a convenient method that makes writing your expire-cookie page very easy: Simply call the PassportIdentity.SignOut method. It takes one argument, which is the path to a gif of a green check mark. The check mark is displayed when the browser deletes the cookies successfully and signs out of your site.

 

Recent privacy rules from the Platform for Privacy Protection (P3P) are designed, among other things, to protect browsers from third-party cookies - cookies created by something other than the site the browser is visiting. Passport's cookies fall into this category and will not be deleted by browsers such as Internet Explorer 6.0 that honor P3P. In order for your site to work with Internet Explorer 6.0 and other P3P-aware browsers, each page on your site that performs a Set-Cookie operation must provide P3P headers. Unless your site creates its own cookies, the only time you need to worry about this is in the expire-cookie page. You must add a P3P mini-header to the page so it will be allowed to delete the cookies. Here is a complete expire-cookie page in VB .NET:

 

<%

  Response.Cache.SetCacheability(HttpCacheability.NoCache)

  Response.AppendHeader("P3P", _

   "CP=""DSP NOI""")

  System.Web.Security.PassportIdentity.SignOut( _

   "signoutcheckmark.gif")

%>

 

This is only an example and it might not represent the security policy of your site. CP="NOI DSP" is the minimum policy required to delete the .NET Passport cookies, but that might misrepresent your site's actual policy if used on a public site. See http://msdn.microsoft.com/library/default.asp?url=/workshop/security/privacy/overview/createprivacypolicy.asp for more details on P3P headers. Don't use CP="TST" as described in some versions of the Passport documentation - it won't work.

 

ASP.NET 1.0 uses the Passport Cookie Path to determine how to delete the cookies. If this path is blank, the cookies might not be deleted properly. Use the Passport Administration Utility to ensure the Cookie Path is set to some non-empty value. Set it to "/" if it's currently empty.

 

Here are some final things to consider when developing authentication procedures with Passport:

 

When developing ASP.NET pages, it's common to browse your pages from the server using the domain name localhost. If you're developing your site within Visual Studio .NET, this domain is used automatically. Unfortunately, if you do this with a Passport page, the GetFromNetworkServer redirect won't work. You should specify the true domain name or machine name of the server.

 

Recent releases of the .NET Passport SDK supported a feature called Inline Sign-In. It allowed you to create your own sign-in page instead of having the user redirected to the Passport login servers. This feature turned out to be a security risk, and Passport dumped it. If you use it, you should remove it and revert to the standard sign-in procedure.

 

.NET Passport 1.4 and 2.1 will not work for authenticating Web Services. A future release will address this need. In addition, .NET Passport works best if Session State is not running: Prohibit your server and browsers to cache the page, and don't save the PassportIdentity object in an object of application or session scope; instead, get a new instance on each page.

 

The .NET Framework and .NET Passport are built into the Windows .NET Server products, so to enable .NET Passport for your ASP.NET Web site, all you need to do is specify in the web.config file. In addition, Windows XP and Internet Explorer 6.0 are .NET Passport-aware. Windows XP and later systems recognize .NET Passport authentication and handle some of the process automatically. The first time you access a .NET Passport site from Windows XP, you'll notice the new .NET Passport pop-up (see FIGURE 6).

 


FIGURE 6: .NET Passport is integrated closely with Windows XP. Signing into Passport on XP with Internet Explorer 6.0 is handled locally and doesn't involve a redirect to the Passport servers.

 

The client system now handles the authentication user interface instead of redirecting you to the .NET Passport login servers. For this to work, the client system must know which .NET Passport environment to authenticate against. Normally, this is the production environment. But when you're developing a site that hasn't yet been released to the world, you're working in the pre-production environment. If you browse to your site from a Windows XP client, you'll see an error like the one in FIGURE 7.

 


FIGURE 7: You must configure your Windows XP and Internet Explorer 6.0 clients to authenticate against the same environment your server uses. You'll see this error if they're mismatched.

 

You must configure your XP and Internet Explorer 6.0 clients to authenticate against the same environment your server uses. The SDK 2.1 help document has details. Look for the topic named .NET Passport SDK: System Requirements. Although your client system is configured for the test environments, you won't be able to browse live sites. This is such a pain that I do most of my testing with a Windows 2000 client.

 

.NET Passport has much more functionality than I could cover in this single article. Take the time to dig into all .NET Passport has to offer. Download the SDK at http://www.passport.com and get the help file from the Microsoft Developer Network (http://msdn.microsoft.com/downloads/default.asp). Select Software Development Kits and then Microsoft Passport SDK from the menu. Explore, have fun, and create the next killer Web application.

 

The files referenced in this article are available for download.

 

Steve Turley is a software development engineer on Microsoft's ASP.NET team. He has been a part of the .NET team from its beginning and has seen it go through at least five code name changes. Steve has more than 20 years of experience writing code for microcomputers and still has his Northstar Horizon with the wooden case. Contact him at mailto:[email protected].

 

 

 

Hide comments

Comments

  • Allowed HTML tags: <em> <strong> <blockquote> <br> <p>

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
Publish