Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Professional ASP.NET Security - Jeff Ferguson

.pdf
Скачиваний:
28
Добавлен:
24.05.2014
Размер:
13.26 Mб
Скачать

The Passport Administration Utility

The Passport Administration utility is used to manage all aspects of implementing and using Passport. It can be used to manage such things as:

Q Changing the environment from test (pre-production) to production, and toggling a site between the two

Q Changing the language ID of a site (as we will see, Passport currently supports a number of different languages)

Q Changing the login expiry - if a ticket is too old, it will be considered invalid (the default is four hours)

Q Connecting and managing a number of sites on the same machine Q Switching keys between sites

Q Changing basic configuration information, such as co-branded cookie URLs, returns URLs, and cookie paths

The changes can be either committed or undone. When changes occur through this application, updates to our web site details will occur on the Passport server. In effect, this is just another interface to the .NET Passport configuration server, and fulfils the same role as the web interface that we encountered earlier.

/ Passpoit Manager Administration

Computer Help

Web Site Name

j D eiauli

Seiver Name

|<Local Host?

InstalDii jCAProgtam

 

 

 

 

 

ForeeSisnfn P Disable Cookies

P Stand Atone Mode f~ Verbose

Mode

FitesVMioosoft Passport Time Window (seconds) 114400

Language ID

Site ID fl~

nURL |

Return L Co-Bran^

A

Disaster URL

| Cookie Oornab

Cookie Path | Consent Cookie

Domab I Change | Consent Cookie Path j

Current |PrePraduEiion

Secure Domain Secure Path

Enai^e Manual Refresh

Refresh Network. Map j DgroTrtt Charges] Undo

Changes

The Passport SDK COM Objects

The Passport SDK is a suite of COM components designed to facilitate exchanges between the client (web server) and the .NET Passport server.

146

.NET Passport

We might programmatically initiate a Passport object in the following way:

Set oMgr = Server.CreateObject("Passport.Manager")

The Passport Manager object will do all the actual login and interaction with the Passport server, exposing a rich set of methods for logging in, enabling us to choose between using implicit login methods or explicit login methods.

It provides complete control over the Passport login process. For instance, one way of enhancing the administrative functionality of our site would be to use the Passport Manager performance monitor counters. This is one way of tracking pieces of information such as new cookies, forced sign-ins, and failed or successful authentication. The monitor works out these values every second, enabling site managers to view real-time behavior of Passport on the site.

The Manager has a header file, which enables applications written in C++ to consume this information (msppcntr. h in C: \Windows\System32\MicrosoftPassport), although C# and VB.NET programmers can use the System.Diagnostics classes, which allow performance counters to be used within .NET applications.

As well as the Manager class, the SDK includes these other classes:

Q Passport.Crypt

Q Passport.Factory

Q Passport.FastAuth

Q Passport.LookupTable

With the Passport. Crypt object we can encrypt anything using the Passport key. There is an upper limit to the amount of data that can be encrypted, but typically only cookies will be encrypted by the web server so the size limit is not really relevant.

The Passport. Factory object can be used to take advantage of object pooling and application-level variable use, enabling many Passport objects to be brokered concurrently.

The Passport. FastAuth object has a different threading model from the Passport .Manager object (the former is free-threaded and the latter apartment threaded). The Passport. FastAuth object is more efficient than the Passport .Manager object because the former can have Application or Session scope, but the latter can only have Page scope (per user). The drawback is that many of the core functions available on the Passport. Manager object are not available on the Passport. FastAuth object. These include necessities such as setting cookies, which will need to be done manually if we use the Passport. FastAuth object.

The Passport. LookupTable object is beyond the scope of this chapter, and has been deprecated within the .NET classes. Its function is to load in the contents of a text file - with comma-separated key-value pairs - and allow an application to use any of these values: they can be anything from site encryption keys to locale IDs: anything that the application can make sense of.

We've briefly looked at these COM classes here so that the one-to-one mapping between the COM Passport classes and .NET Passport classes will be evident. In fact, testing through VS.NET reveals a stack trace, which provides specific details of COM Interop between the .NET Passport classes and the COM classes outlined here.

•1/17

This should give you some idea of the layout of the SDK and the COM objects present (and what they do). We'll now move on to discuss the creation of a web project that enables resources to be protected, and the Passport user's identity to be known. Initially, this project will involve creating a simple ASP.NET Web Application.

The .NET Passport Classes

The .NET Framework class library provides us with classes that allow us to interface with Passport.

The Passportldentity Class

Passportldentity is an implementation of Ildentity that includes properties and methods specific to Passport authentication.

We could use Passportldentity in the following way to determine whether or not a user is logged into .NET Passport. If a user is logged into .NET Passport, the user ID will be displayed.

Passportldentity pldent =

(Passportldentity)Context.User.Identity;

 

if(pldent.IsAuthenticated)

 

 

 

 

 

 

 

{

 

 

 

 

 

 

 

 

 

Response.Write("Sucessfully logged into .NET Passport");

 

 

Response.Write)"<BR>"&"Your unique ID is: "Spldent.HexPUID); }

 

else {

 

 

 

 

 

 

 

 

 

Response.Write("To log

into

.NET

Passport click

the

link below<BR>");

Response.Write(pldent.LogoTag2(null,

600,

true,

true,

null,

1033,

false,

null, 0,

false)); }

 

 

 

 

 

 

 

This code uses the IsAuthenticated property, which returns a Boolean value to indicate whether the user has been authenticated using .NET Passport. If a Passport ticket is detected then this property will return True. The user ID is a PUID (Passport User ID - accessed in this code by pldent. HexPUID).

This is a unique 64-bit value given to every .NET Passport user by which they may be uniquely identified.

This value may be used as a primary key in a database table. For instance, it may be used to add personalization: information about users' interests can be held by storing site-specific information indexed by the user's PUID.

The LogoTag2 method generates a small icon on which the user must click to log in to our application. It has three constructors, and can take variations of the following parameters in two of them. These are indexed below in the order in which they occur, using the constructor described in the code example below:

1 . The strReturnUrl parameter defines the URL to return to, if different from the URL the request is being sent from. Any strings using the return URL will be URL encoded.

2 . The iTimeWindow parameter defines whether valid tickets are acceptable within a defined time period. In our code example, we use 600 seconds, which is the default. If a ticket is valid but the time has expired (each ticket having a timestamp on it) then a new login will need to be forced onto the user.

148

.NET Passport

3. We set the f ForceLogin parameter to True if we wish to force the user to log in, irrespective of whether they have logged into .NET Passport and have the appropriate cookies needed for a seamless login.

4. The strCoBrandedArgs parameter enables us to control a co-branded script template, which will be shown on the registration page. This is done by specifying query

string parameters.

5. The iLanguageld parameter (we have used 1033) specifies that we want all Passport login and text in English; however, many other languages are supported. We'll look at how to utilize this later.

6. Secure login requires the use of HTTPS (through SSL) and the f Secure parameter defines whether HTTPS should be used or not - this use of HTTPS specifies if Passport should redirect the user back to a secure page on our site.

7. The strNameSpace parameter enables us to represent the domain within which we use Passport - this will default to whichever site is being currently used to log in: the site the page resides in. As multiple sites can be hosted on the server using multiple domains, this is useful to determine which domain is being used.

8 . The iKpp parameter specifies whether the COPPA-compliant data collection policy is to be used with reference to Kids Passport and privacy.

9. The last parameter - bUseSecureAuth - is used to request the Passport login page using HTTPS. By default, it will not request this, but for added security, all sensitive information transmitted across the internet should be encrypted using HTTPS.

As an example, the LogoTag2 method may be used with one of the Passport Login methods in the following way:

p!dent.LogoTag2(null,

600,

true,

true,

null,

1033,

false,

null,

0,

false)

 

 

 

 

 

 

 

 

The use of nulls in this method call will mean that some default site values will be used by the Passportldentity class.

The LogoTag2 () method will produce the following text (it should be noted that all the methods that belong to the Passportldentity class do nothing more than output HTML). This is the result of the LogoTag2 () method call shown from the previous code segment:

<A HREF="?msppchlg=l&mspplogin=http://current-login, passporttest.com/login.srf%3Flc%3D1033%26id%3D23693%26ru%3D%26tw%3D600%26fs% 3Dl%26kv%3Dl%26ct%3D1016826863%26ems%3Dl%26ver%3D2.1.0173.l%26tpf%3Df1658c6dlb9b8d Ifc2ab0ce617a9ed82">

<IMG SRC="http://current-www.passportimages.org/1033/signin.gif" CLASS="PassportSignIn" BORDER="0" ALT="Sign in with your .NET Passport"/></A>

There are some interesting observations to be made about this.

1/1 a

Firstly, there is encoding in the query string, which can be attributed to the data compression and URL encoding (which we'll look at later).

Secondly, the request is directed locally and redirected to the Passport login web site instead of directly calling the Passport login web site - this is because for absolute flexibility the location of the Passport server is configurable in the registry so that different environments can be toggled for different login purposes.

Thirdly, Passport images are not stored locally. They are stored on the Passport server, enabling them to be changed centrally rather than by redeploying an updated SDK.

.NET Passport Login

The Graphical Web UI for logging in to .NET Passport will vary depending on the environment of the user and the method used. The prompt using the login methods may be automated (the user requests to see a page, and faces a login prompt or form) or can be invoked from a hyperlink or a .NET Passport image.

Alternatively, we may require the user to log in using the co-branded web page (as we saw earlier, the URLs for our logo or other branding images should be specified during the registration process).

Changing the iLanguageld parameter from 1033 to 1034 will result in different text during the sign-in process. This is achieved through the LogoTag2 method, by changing the locale parameter, as listed above. There is currently support for over 27 languages.

Iniciar Sesion ,^|

We may require our users to log in to .NET Passport by pressing a button. There may, however, be instances where we may want users to click on a link, automatically log in to the .NET Passport server, or be transferred to the Passport sign-in page without any prior interaction. All these types of scenarios can be managed via the .NET Passport API.

Bear in mind that some of the methods the API exposes are now deprecated, since the initial Passport version 1.4 has now been superseded by the .NET Passport SDK 2.1.

Login Methods

Another useful method, which takes the same arguments as the LogoTag2 () method (as defined and described in the list earlier), is the AuthUrl2 () method. This method enables us to customize the UI by using the Passport classes to generate a hyperlink that can be used for login purposes (users that click on the link will face a .NET Passport login screen):

pIdent.AuthUr!2()

Using this method will allow unique branding to be added to the Passport-enabled link. For example, if we rewrote some of the code on the login page to display an HTML link, then the following could be used. We might also use an HTML IMG tag to display a branded login for .NET Passport.

Response.Write("<A HREF=\"");

Response.Write(pldent.AuthUrl2(null, 600, true, null, 1033, null, 0, false)); Response. Write ("\ ">Click on the link to login to Passport</A>");

150

.NET Passport

The result of the above code would be:

<A

HREF="http://62.3.69.4/PortalLogin/login.aspx?msppchlg=l&mspplogin=http://current-logi n, passporttest.com/login.srf%3Flc%3D1033%26id%3Dl%26ru%3Dhttp://62. 3 . 69.4/Port alLogin/login.aspx%26tw%3D600%26fs%3Dl%26kv%3Dl%26ct%3D1018186168%26ems%3Dl%26ver% 3D2.1.0173.!%26tpf%3Dcbb36f09692c7374cOf0157aebla4628">Click on the link to

login to Passport</A>

Anything used in this way to define a changing UI for access to .NET Passport would have to abide by the .NET Passport guidelines given for production implementation (which may be found within the Passport documentation).

One other useful method enabling automated login access to .NET Passport is:

pldent.LoginUser(null,

600,

true,

null,

1033,

null,

0,

false,

null);

In many circumstances using LoginUser may be the most preferable approach as it is relatively straightforward, and users logging into private areas of the site can face an immediate login prompt (if using IE 6), or be transferred to the .NET Passport sign-in page, rather than having to click on a link or image to be transferred to the login page.

This is where the strReturnUrl parameter (introduced in the argument list earlier) is useful. It will enable a return the resource requested before the .NET Passport redirection following a successful .NET Passport authentication. This can take place without any ASP.NET session handling.

When developing a Passport-enabled application and considering the most appropriate login method it's a good idea to consider the logout method used. When users have signed-in using the LogoTag2 () method, when called again, this will present a sign-out graphic instead of a sign-in graphic. This is incredibly useful, as many users will want to see something visible to enable them to sign-out. This has become a Passport standard now, with many sites implementing it, so many Passport users are familiar with it.

The sign-out link should be directed to the logout URL. The logout is a simple - all cookies should be manually deleted within the Passport partner site domain along with those specifically representing the Passport login.

Handling Passport Cookies

Using a small piece of stub code we can enumerate the cookies that Passport has placed on our system:

for(int i = 0; i < Request.Cookies.Count; i++) { Response.Write)"Cookie name: "+Request.Cookies[i].Name+"<br/>"); Response.Write("Cookie value: "+Request.Cookies[i].Value+"<br/>"); Response.Write("<BR/>");

}

This will enumerate the cookie values and display all the cookie values. From this (or the documentation) we can extrapolate the cookie values that need to be deleted to ensure that logging out of Passport will occur. This cookie deletion is not handled by the Passport classes: it is a manual process.

The cookie names and values are as follows:

Cookie name: MSPAuth Cookie value:

lTSgliOgkDXpFLBpOTYdPsM81qSPP2FZR!YPwHtCZSTi9tMZlio*gLtsxKrECZ2PX20g6S60hkH03JfOOn Rq9FTg$$

Cookie name: MSPProf Cookie value:

!TSgliOgkFWBKebuY4y!jMZEVFffzPNOfG6cw94DNNBEa8bWkmWDPFDpuERFGBnReLRe26bfYQ4RHXvOKt

xh*aOmF*lWytFVzDOr*8Lt7f6S15q*yKbv4bQNuswkSrLnEYeaRVFFh88eGb3*9vsGQldrqfLFGy9xJz69 NMX!privLMScfpNCs9Qw$$

The first cookie - MSPAuth - contains the .NET Passport ticket that enables access to resources. This ticket contains a time stamp defined by configuration parameters within the Passport Administration Manager utility. This enables it to be invalidated after a certain period of time, forcing the user to log in to the site again.

The second cookie - MSPProf - contains a Passport profile (which we'll discuss and code against later). The profile enables the site to extract information that can be used to populate forms, including e-mail addresses and any other information specified by the Passport user that they wish to share with web sites.

Logging the User Out of .NET Passport

To delete the two .NET Passport cookies set on our site domain, we may use the following code:

Response.Cookies["MSPAuth"].Value

=

" " ;

 

Response.Cookies["MSPAuth"].Path

=

"/";

 

Response.Cookies["MSPAuth"].Expires

= Convert.ToDateTime("1900-01-01T12: 0 0 : 0 0 " );

Response.Cookies["MSPProf"].Value

 

=

"";

Response.Cookies["MSPProf"]-Path

=

"/";

Response.Cockiest"MSPProf"].Expires

=

Convert.ToDateTime("1900-01-01T12:00:00");

This simple stub code will cause the cookies to expire. If the LogoTag2 () method is called while the user is already logged in, then a sign-out image link will appear, and when the user presses this, they will be redirected to the logout URL on the web server. This should contain this cookie expiry code, or possibly code to delete the whole cookies collection:

Response.Cookies.Clear()

The logout URL may be specified either through the Passport Administration utility or through the Passport Management web site.

In the same kind of way as we established the Passport login HTML link, we can utilize the LogoutURL () method. This will return the URL of the Passport logout page, thus enabling us to delete all the Passport cookies, and log off the user. Of course, the logout URL page doesn't have to contain cookie expiration or deletion code, but typically that is what it should contain in order to log the user out.

Response. Write ("<BR/xA

HREF=\"") ;

 

 

 

Response.Write(pldent.LogoutURL());

 

 

 

Response.Write("\">Click

on

the

link to

LOGOUT of

Passport</A>");

152

.NET Passport

Configuring ASP.NET for Passport Authentication

As we have seen elsewhere, the web.conf ig file holds the application's configuration, and should be left in the root of the web site or the virtual directory, web. conf ig holds information such as session state information, web page trace settings, default (server-side) languages used in ASPX pages, globalization info, and application-specific information. As we have seen elsewhere, a useful feature of the web. conf ig file is that we can use it to set authentication and authorization settings.

We can specify the type of authentication we wish to use in the following way:

authentication mode="Passport"> <passport redirectUrl="login.aspx"/>

</authentication>

Of course, the appropriate authorization resources also have to be in place, so this line in the web. conf ig file will have no effect unless something is added to allow the protection of some or all resources.

Let's suppose that users have to log into .NET Passport before viewing pages. The following will ensure that all resources are protected using .NET Passport: if the user requesting the resource hasn't logged into Passport, they'll be redirected to the login.aspx page in our sample application specified in the redirectUrl attribute.

<authorization> <deny users="?"/>

</authori zation>

One way of protecting certain resources within an application is to apply this model on each virtual directory that needs protecting. For example, a site may contain some files that only Passport users can see, in this way a virtual directory should be created with the above settings specified in the web. conf ig file. This approach can be useful since it will allow different web. conf ig files to have different security models for different parts of our site or application.

Each authenticated request has an associated user identity. This identity may be based on any one of the mechanisms described (that is, WindowsAuthentication, FormsAuthentication, or PassportAuthentication). In this way the identity of each user is known to the site and is encapsulated upon request.

The Passport identity is acquired by ASP.NET using some of the cookie handling and decryption functionality contained in the Passport SDK. In this way there is a need for something that will broker user access with an identity in ASP.NET in the same way as there is for standard Windows logins. We shall return to this later in the chapter, while considering authentication providers.

Once the user has logged on successfully through .NET Passport the identity of the user can be determined in the following way:

Passportldentity pldent =

(Passportldentity)Context.User.Identity,•

The user must be logged in before the above code can be used. If the user doesn't have an identity (hasn't logged in yet) then the cast to Passportldentity from Genericldentity type will fail, as the Genericldentity of the user will be null. This method of obtaining a Passportldentity object can be extremely useful for generic components on a web site, which might have to cater for a variety of login methods.

Getting Profile Data

One of the useful features of .NET Passport is its support for profile information. Users can enter as much or as little information as they want for a profile, and determine whether or not this information will be disclosed to sites or not. The added benefit of this is that sites that support .NET Passport can implement pre-populated web forms that contain the name and address data, which would otherwise need to be entered. There is very granular control over what bits of information can be exposed to the web site, as is evident from the .NET Passport edit profile edit screen.

The following simple method retrieves all the profile details using the GetProf ileObject () method. The .NET Passport documentation contains a full list of all the profile objects that can be retrieved - the more common ones can be seen in the following code.

The Passportldentity class uses a property indexer to allow all the profile objects to be directly retrieved through a name. For example, to retrieve the FirstName of the Passport user, we can use pldent [ "FirstName" ]. Similarly, all the other profile properties can be retrieved in the same way. The HasProf ile ("FirstName") will return a Boolean value to determine whether or not the user has a profile value listed for FirstName. If a profile string is used that is invalid (there is no such profile object in existence) then an exception is thrown:

private void ListPassportProfile(Passportldentity pldent) { try {

Write(pldent.GetProfileObject("Accessibility"));

Write(pldent.GetProfileObject("birthdate")); Write(pldent.GetProfileObject("directory")) ; Write(pldent.GetProfileObject("flags")); Write(pldent.GetProfileObject("gender")); Write(pldent.GetProfileObject("Lang_Preference")); Write(pldent.GetProfileObject("FirstName")); Write(pldent.GetProfileObject("lastname")); Write(pldent.GetProfileObject("NickName")); Write(pldent.GetProfileObject("PreferredEmail" Write(pldent.GetProfileObject("profileVersion" Write(pldent.GetProfileObject("postalCode")); Write(pldent.GetProfileObject("country")); Write(pldent.GetProfileObject("region")); Write(pldent.Name); }

catch(Exception e) { throw e;

154

.NET Passport

rivate void Write (object o) f Response.Write(o);Response.

Wr ite ( "<BR>" ) ;

)

upplementary information can also be obtained from the Passportldentity enabling us to

see .^cr the password has been saved, how old the ticket issued by Passport is, and how much time has ,ed since the last sign-in. With the ability to save encrypted passwords comes the ability to licitly log in to all sites without re-entering information.

NET Passport can be used to store cookies on the client machine. But, as we've seen, these will only last as l°ng as me ticket issued by the .NET Passport TGT (Ticket Granting Ticket) hasn't expired - this is something that will occur as all tickets have a timestamp encoded within them that, when decrypted, can be checked to see if the timestamp valid period has been passed. Passwords can be saved, however, and encrypted into the contents of a cookie, which enables login to occur implicitly, without the user having to re-enter details. This will be the case unless the ForceLogin option - described earlier in the chapter - is used, in which case the user will have to re-enter credentials.

private void Suplnfo (Passportldentity pldent)

Write (pldent .HasSavedPassword) ; Write (pldent .TicketAge) ; Write (pldent .TimeSinceSignln) ;

We have

^e have a great degree of control over what the user sends to the web site, and what the web site can access and use to populate forms. This control is managed via static methods, which are exposed by the Passportldentity class. Many of the .NET technologies have been incorporated fully with the Passport implementation: for instance, we've seen the use of indexers and HttpModules to associate access with user identity.

Customizing Passport Authentication

We can customize the behavior of the Passport authentication module by handling the Authenticate event that it exposes. The Authenticate event is raised each time the Passport authentication module performs an authentication (with every page request).

For example, we can handle this event in the global. asax in order to check the Passport User ID (PUID) against a list of banned users:

Protected void

PassportAuthentication_Authenticate(object

sender,

PassportAuthenticationEventArgs

e)

 

if( e . Identity!=null&&(e.Identity).IsAuthenticated)

 

Passportldentity pldent

=

e.Identity;

 

string tmpPuidVal

= pldent.HexPUID;

 

XmlDocument

xmlDoc

=

new

 

 

XmlDocument();

155

Соседние файлы в предмете Программирование