Authentication

Published on December 2016 | Categories: Documents | Downloads: 38 | Comments: 0 | Views: 657
of 16
Download PDF   Embed   Report

Comments

Content

Expert Reference Series of White Papers

Effective Use of Authentication Concepts to Enhance Web Security
1-800-COURSES www.globalknowledge.com

Effective Use of Authentication Concepts to Enhance Web Security
Antoine Victor, Senior Global Knowledge Training Consultant

Introduction

Many things in a standard web application require identity information about the users, from displaying a custom welcome message to allowing users to view a shopping basket created on their last visit to the site. Simply being able to display relevant information to a few different users can be a difficult task if you can’t tell one user from the other. Authentication is the process of determining a user’s identity, usually by requesting a user name and password, and validating that identity against some secure identity store. Once we know who the user is, we can do all sorts of interesting things. For example, we can display weather in their neighborhood, show them their shopping cart, and determine if they are authorized to access membersonly resources in the application. The problem with requesting a user’s identity is that it requires the user to send very private information (username and password) with out anyone else gaining access to this identity information. ASP.NET works in conjunction with the Microsoft.NET Framework and IIS to provide the infrastructure for Web application security. To secure an ASP.NET application, you must take into account three fundamental functions: • Authentication – Who goes there? What is the identity of the user that is accessing your site? • Authorization – What is your clearance level? Is the user accessing your site authorized to use the resource they are requesting? • Impersonation – Whose card key do you have? Should the user be giving access to the resource using their identity or the identity of the ASP.Net process or some other user account? Let’s begin our discussion of ASP.Net authentication with an overview of authentication concepts. We’ll start with an overview of the ASP.Net page request process, then move into the different authentication modules. When discussing authentication we must also discuss identity roles and principals, but we’ll get into that towards the end of this paper. The concept of authorization as well as impersonation will be discussed in later sections of this article. In this paper you will learn the following: • What authentication providers ship with .NET. • How to choose an authentication type. • How to use Identities and Principals. • How Roles and Method-level security work.

Copyright ©2005 Global Knowledge Network, Inc. All rights reserved.

Page 2

What Is Authentication?

Authentication is the process of discovering a user’s identity and determining its authenticity. The process is very similar to entering a hotel. First the doorman lets you in, if you don’t look too shabby (possibly from a restricted domain) then you can move around the common areas—the lobby, the lounge, and so forth. If you want to get into a hotel room, you have to provide some means of authentication: a key, a smart card, or possibly a numeric code. The means of authentication is chosen by the hotel you are visiting. The hotel uses their chosen authentication provider (MasterLock standard key entry or HID Corp PoxCard smart card entry) and issues you an authentication ID. Once you have been assigned your authentication ID, you can use it to access resources for which you are authorized. Once you have supplied your authentication key, a system determines if you are “authorized” to access this restricted area. In a web-based application, when a user enters a restricted area of a web site, the user is generally prompted to log in. Accessing secured web resources is a two-part process, which consists of “authenticating” the user’s identity and then verifying the user’s “authorization level” for the select web page or resource. It is important to understand the difference between authentication and authorization. For instance, if you have an account at a bank, and I have an account at the same bank, both of our identities are known to the bank. Authentication happens when I enter the bank to make a withdrawal and provide the teller with my account number and my driver’s license. The teller then verifies my identity with my license. The teller checks to see if my identity is “authorized” to access the resources that I have requested. In this case, I have asked for the money in your account. The point of this metaphor—just because the teller has verified who I am (authentication) doesn’t mean that I can take money out of your account (authorization).

Why Do We Need Authentication?

There are several reasons why authentication is important, from unsecured personalization to very secure banking transactions. At the lower security end of the spectrum, there are basic personalization features such as “My Weather”, “My News”, and other types of services provided by most major portal sites. The sites do not contain any confidential information, so the security requirement is not the reason for authentication. In this scenario the issue is “How do I get your news and your weather back to you?” The first thing I have to do is figure out who you are! Once I am satisfied that you are who you say you are, I’ll display “your weather” because I probably have other information stored with your identity about where you live. In a high security environment authentication is necessary to determine identity for the purpose of authorization. In a secure environment, we want to know who you are so that we can check your “security clearance” to see if you are authorized to access a certain resource. In web-based applications it is common to have both common areas and restricted areas on the site. The common areas do not require authentication because we want all visitors to be able to see our home page and product list. However, when a customer attempts to make an

Copyright ©2005 Global Knowledge Network, Inc. All rights reserved.

Page 3

order for one of our products, we need to collect some information about that user. We can prompt the user to login or create a new account if he or she doesn’t already have one. As the user creates the new account, we have an opportunity to collect the information we need to validate the user’s identity and process orders. We might collect things like “User Name”, “Password”, “Address”, and “Phone Number”. We can then associate this information with the user’s authenticated identity. When a user logs in, we can reference the associated user information, like “Address”, to insert it into an orders “Ship To” address field. Or perhaps the next time the user logs in, he will be presented with the welcome message “Welcome back, Antoine.”

Authentication in ASP.NET
The ASP.NET Page Request
When a user requests a page, IIS checks to see if the user making the request has been authenticated. If the user has been authenticated, his or her authentication token is passed on to the server. The authentication token can be created when the user identity is confirmed and then stored on the user’s pc in the form of a persistent cookie. On subsequent requests the user’s authentication ticket is sent to validate identity (see diagram). After the user’s identity is verified, the user is allowed to access pages for which the “authenticated identity” has been “authorized”. Page Request Events (per request): Application_BeginRequest This event fires when the user request first comes into ASP.Net. Application_AuthenticateRequest Occurs when a security module has established the identity of the user. Application_AuthorizeRequest Occurs when a security module has verified user authorization. Application_ResolveRequestCache Caching modules serve requests from the cache, bypassing execution of the handler. Application_AquireRequestState ASP.NET acquires the current state (ie session state) associated with the current request. Application_PreRequestHandlerExecute Occurs just before ASP.NET begins executing a handler such as a page or XML Web service. Application_PostRequestHandlerExecute Occurs when the ASP.NET handler (page, XML Web service) finishes execution. Application_ReleaseRequestState Occurs after ASP.NET finishes executing all request handlers. This event causes state modules to save the current state data. Application_UpdateRequestCache Occurs when ASP.NET finishes executing a handler in order to let caching modules store responses that will be used to serve subsequent requests from the cache.

Copyright ©2005 Global Knowledge Network, Inc. All rights reserved.

Page 4

Application_EndRequest Occurs as the last event to in the HTTP pipeline chain of execution when ASP.NET responds to a request.

The Web.Config File Authentication Section

<authentication mode="Windows|Forms|Passport|None"> <forms name="name" loginUrl="url" protection="All|None|Encryption|Validation" timeout="30" path="/" > <credentials passwordFormat="Clear|SHA1|MD5"> <user name="username" password="password" /> </credentials> </forms> <passport redirectUrl="internal"/> </authentication>

Required Attribute Attribute Description Mode Controls the default authentication mode for an application.

Copyright ©2005 Global Knowledge Network, Inc. All rights reserved.

Reprinted courtesy of Microsoft Corporation.

Page 5

Options Windows Forms None

Description Specifies Windows authentication as the default authentication mode. Use this mode when using any form of Internet Information Services (IIS) authentication: Basic, Digest, Integrated Windows authentication (NTLM/Kerberos), or certificates. Specifies ASP.NET forms-based authentication as the default authentication mode. Specifies Microsoft Passport authentication as the default authentication mode.

Passport

Specifies no authentication. Only anonymous users are expected or applications can handle events to provide their own authentication. Description Configures an ASP.NET application for custom forms-based authentication.

Subtags Subtag <forms>

<passport>

Specifies the page to redirect to if the page requires authentication and the user has not signed on with Passport.

The following example configures a site for forms-based authentication, specifies the name of the cookie that transmits logon information from the client, and specifies the name of the logon page to use if initial authentication fails.
<configuration> <system.web> <authentication mode="Forms"> <forms name="401kApp" loginUrl="/login.aspx" /> </authentication> </system.web> </configuration>

The Authentication Manager

The authentication manager class manages the authentication modules that an application uses. The authentication modules give us a standard interface with which to access the security subsystem in .NET. When a user makes a request to a restricted resource, the authentication manager calls the authenticate method. The authenticate method calls the authenticate method on each of the registered authentication providers until one responds to the authentication request. The authentication provider returns an instance of the authorization class that can then be used for future authentication requests. If no authentication module can respond to the request, a “Nothing” is returned (In Visual Basic). The authentication modules are called in the order in which they were registered in the authentication manager. Modules that provide the Basic, Digest, Negotiate, NTLM, and Kerberos authentication (Windows) as well as a Forms Authentication and Passport Authentication Modules are registered with the authentication manager by default. You can add additional authentication modules that implement the IAuthenticationModule interface using the register method. The register method adds authentication modules to the end of the list of modules called by the authenticate method. authentication modules are called in the order in which they were added to the list.
Note: The Kerberos and Negotiate authentication types are not supported on Windows 95/98 or Windows NT 4.0

Copyright ©2005 Global Knowledge Network, Inc. All rights reserved.

Page 6

The authentication manager has the following members: Public Methods: RegisteredModules - Shared Property Public Methods: Authenticate – Shared Method Equals (inherited from Object) GetHashCode (inherited from Object) GetType (inherited from Object) Register – Shared Method Returns a list of authentication modules that are registered with the authentication manager. Calls each registered authentication module to find the first module that can respond to the authentication request. Overloaded. Determines whether two Object instances are equal. Serves as a hash function for a particular type, suitable for use in hashing algorithms and data structures like a hash table. Gets the Type of the current instance. Preauthenticates a request.

PreAuthenticate – Shared Method ToString (inherited from Object) Unregister – Shared Method

Registers an authentication module with the authentication manager.

Overloaded. Removes authentication modules from the list of registered modules.

Returns a String that represents the current Object.

Protected Methods: Finalize (inherited from Object)

MemberwiseClone (inherited from Object)

Overridden. Allows an Object to attempt to free resources and perform other cleanup operations before the Object is reclaimed by garbage collection. In C# and C++, finalizers are expressed using destructor syntax. Creates a shallow copy of the current Object.

What an Authentication Module Does

Authentication is implemented in ASP.NET through the use of Authentication providers. Authentication providers are the code modules that contain the code necessary to authenticate the requestor's credentials. The authentication modules give us a standard interface with witch to access the security subsystem in .NET. The programming to use a particular authentication type is simplified by using the authentication providers because of the standard interface provided. Using Authentication modules from your asp.net code to access authentication types and identity stores is very similar to using ADO (ActiveX Data Objects) to access a database. You use a standard syntax for connecting to the database and getting data out. But just by changing the data provider (Database Driver), you can change the type of data store that you retrieve your data from. All authentication modules expose the IAthenticationModule interface. This gives the Authentication module a standard set of properties and methods that can be

Copyright ©2005 Global Knowledge Network, Inc. All rights reserved.

Page 7

used to authenticate your users. The use of the standard interface on all authentication providers makes changing your authentication strategy a very straight-forward process. The IAuthenticationModule interface exposes the following members: Public Properties: AuthenticationType CanPreAuthenticate Public Methods: Authenticate PreAuthenticate Gets the authentication type provided by this authentication module.

Gets a value indicating whether the authentication module supports preauthentication. Returns an instance of the Authorization class in respose to an authentication challenge from a server.

Returns an instance of the Authorization class for an authentication request to a server.

An Identity represents the authenticated user. The type of Identity object depends on the type of authentication you are using. For instance, Windows authentication returns a Windows Identity. A principal object, on the other hand, represents the group or role membership of the authenticated user. While it’s created automatically with the Windows authentication in IIS, it is possible to create a generic principal object on the fly with user and role data from a custom identity store that you define. All identity and principal objects implement the IIdentity and IPrincipal interfaces respectively.

Identities and Principals

GenericIdentity

You can use the GenericIdentity class in conjunction with the GenericPrincipal class to create an authorization scheme that exists independent of a Windows NT or Windows 2000 domain. For example, an application that uses these two objects might prompt a user for a name and password, check them against a database entry, and create identity and principal objects based on the values in the database. The GenericIdentity is minimal implementations of the IIdentity interface. The Generic Identity Class has the following members: Public Constructors: GenericIdentity Constructor Public Properties: AuthenticationType IsAuthenticated Overloaded. Initializes a new instance of the GenericIdentity class. Gets the type of authentication used to identify the user.

Gets a value indicating whether the user has been authenticated.

Copyright ©2005 Global Knowledge Network, Inc. All rights reserved.

Page 8

Name Public Methods: Equals (inherited from Object) GetHashCode (inherited from Object) GetType (inherited from Object) ToString (inherited from Object) Protected Methods: Finalize (inherited from Object)

Gets the user's name. Overloaded. Determines whether two Object instances are equal.

Serves as a hash function for a particular type, suitable for use in hashing algorithms and data structures like a hash table. Gets the Type of the current instance. Returns a String that represents the current Object. Overridden. Allows an Object to attempt to free resources and perform other cleanup operations before the Object is reclaimed by garbage collection. In C# and C++, finalizers are expressed using destructor syntax. Creates a shallow copy of the current Object.

MemberwiseClone (inherited from Object)

Generic Principal Object

A Generic Principal object can be created based on your own custom roles. The GenericPrincipal is minimal implementation of the IPrincipal interface. You will use this when you have your own user/role database. The Principal object is populated in the OnAuthenticate event. You may have a custom table mapped to Windows accounts that you map in this event. In any case, you can create a custom Principal object for that particular user. For returning users who have already been authenticated, you could use a cookie to recreate the Principal object for the returning user. The Generic Principal Object has the following members: Public Constructors: GenericPrincipal Constructor Initializes a new instance of the GenericPrincipal class from a GenericIdentity and an array of role names to which the user represented by that GenericIdentity belongs. Gets the GenericIdentity of the user represented by the current GenericPrincipal. Overloaded. Determines whether two Object instances are equal.

Public Properties: Identity Public Methods: Equals (inherited from Object)

Copyright ©2005 Global Knowledge Network, Inc. All rights reserved.

Page 9

GetHashCode (inherited from Object) GetType (inherited from Object) IsInRole ToString (inherited from Object) Protected Methods: Finalize (inherited from Object)

Serves as a hash function for a particular type, suitable for use in hashing algorithms and data structures like a hash table. Determines whether the current GenericPrincipal belongs to the specified role. Gets the Type of the current instance.

Returns a String that represents the current Object.

MemberwiseClone (inherited from Object)

Overridden. Allows an Object to attempt to free resources and perform other cleanup operations before the Object is reclaimed by garbage collection. In C# and C++, finalizers are expressed using destructor syntax. Creates a shallow copy of the current Object.

Windows Identity Object

Windows Identity Object represents a Windows user. Which user the Windows Identity represents depends upon the configuration of IIS and your ASP.Net application. The Windows Identity Object implements the Identity class. The Windows Identity Object has the following members: Public Constructors: WindowsIdentity Constructor Public Properties: AuthenticationType IsAnonymous IsAuthenticated IsGuest IsSystem Name Token Public Methods: Equals (inherited from Object) Overloaded. Initializes a new instance of the WindowsIdentity class. Gets the type of authentication used to identify the user. Gets a value indicating whether or not the user has been authenticated by Windows.

Gets a value indicating whether the user account is identified as an anonymous account by the system.

Gets a value indicating whether the user account is identified as a Guest account by the system. Gets a value indicating whether the user account is identified as a System account by the system. Gets the Windows account token for the user. Overloaded. Determines whether two Object instances are equal.
Page 10

Gets the user's Windows logon name.

Copyright ©2005 Global Knowledge Network, Inc. All rights reserved.

GetAnonymous Shared Method GetCurrent Shared Method GetHashCode (inherited from Object) GetType (inherited from Object) Impersonate ToString (inherited from Object) Protected Methods: Finalize MemberwiseClone (inherited from Object)

Returns a WindowsIdentity object that represents an anonymous Windows user. Returns a WindowsIdentity object that represents the current Windows user. Serves as a hash function for a particular type, suitable for use in hashing algorithms and data structures like a hash table. Gets the Type of the current instance.

Overloaded. Allows code to impersonate a differ ent Windows user.

Returns a String that represents the current Object.

Overridden. See Object.Finalize. In C# and C++, finalizers are expressed using destructor syntax. Creates a shallow copy of the current Object.

The System.Security.Principal namespace within the .NET Framework Class Library (BCL) provides a WindowsPrincipal object to represent the security context under which the code is running. This object is created for you automatically when you use Windows authentication in IIS. It allows you to check the Windows group membership of a Windows user and restrict access accordingly. The Windows Principal Object has the following members: Public Constructors: WindowsPrincipal Constructor Public Properties: Identity Public Methods: Equals (inherited from Object) GetHashCode (inherited from Object) GetType (inherited from Object) IsInRole ToString (inherited from Object) Initializes a new instance of the WindowsPrincipal class from a WindowsIdentity object. Gets the identity of the current principal. Overloaded. Determines whether two Object instances are equal.

Windows Principal Object

Overloaded. Determines whether the current prin cipal belongs to a specified Windows user group.

Serves as a hash function for a particular type, suitable for use in hashing algorithms and data structures like a hash table. Gets the Type of the current instance.

Returns a String that represents the current Object.

Copyright ©2005 Global Knowledge Network, Inc. All rights reserved.

Page 11

Protected Methods: Finalize (inherited from Object)

MemberwiseClone (inherited from Object)

Overridden. Allows an Object to attempt to free resources and perform other cleanup operations before the Object is reclaimed by garbage collec tion. In C# and C++, finalizers are expressed using destructor syntax. Creates a shallow copy of the current Object.

Roles and Method-Level Security

You may need to use method-level security to restrict particular methods being called by particular client principals. There are several approaches to this problem. If you are using Windows accounts, create roles for your users in the form of Windows Groups. Because the ASP thread will be impersonating the client and you will have a Windows Principal object available, use the following approaches: • Create ACLs (Access Control Lists) on protected resources accessed by the ASP.NET thread. • Call the IsInRole method on the WindowsPrincipal object from each method to verify the caller has the appropriate permissions. You may also implement a logic statement in code that calls a particular sub-routine based on the client's group membership.
Note: The Access control list is simply a list of the users or groups of users that are authorized to access a particular resource.

The IsInRole method returns true if the current user (WindowsPrincipal) is a member of the specified group. If you are using a Generic Principal object created from users and roles contained in a custom database, you can programmatically check role membership by calling the IsInRole method on the Principal object in the same fashion as with the Windows Principal object described above. Method-level security in its simplest form ends up as an “if statement” that checks to see if the caller IsInRole. If the calling client is a member of the specified role (or group), the IsInRole method returns true. So your statement would look something like this:
Public Sub DeleteAllOfOurCustomerRecords() 'create a windows principal object from the current windows identity Dim MyWinIdent As New System.Security.Principal.WindowsPrincipal _ (System.Security.Principal.WindowsIdentity.GetCurrent) 'check the role membership of the curent identity If MyWinIdent.IsInRole(System.Security.Principal.WindowsBuiltInRole. Administrator) Then 'DeleteCustomers 'send electronic pink slip

Copyright ©2005 Global Knowledge Network, Inc. All rights reserved.

Page 12

Else

'Don't DeleteCustomers 'send electronic pink slip End If End Sub

If you are not using a Principal object, you have other options: • Accept user credentials as parameters to the method call and perform a lookup. • Verify the existence of a cookie as the first operation of the method call. • Create a logon method that returns a custom key value. Subsequent methods accept the key value as a parameter. This is similar to using browser-supported cookies; however, it could be used in cases where cookies are not supported by the client. You can store identity information in SQL, Active Directory, or anyplace else. This information at the least should be stored as user/password pairs.

Choosing an Authentication Type

The authentication type that you choose depends on the type of site you are building, the number of authenticating users you are expecting, and whether your ASP.net application and users will be on different sides of the firewall. The authentication type that you choose will also directly affect the Authentication provider that you use to implement Authentication. ASP.NET uses Windows authentication in conjunction with IIS authentication. Authentication is performed by IIS in one of three ways: basic, digest, or Integrated Windows Authentication. When IIS authentication is complete, ASP.NET uses the authenticated identity to authorize access. IIS Authentication happens before the resource request is passed to your ASP.Net application; it may be necessary to enable anonymous access in IIS to allow your ASP.Net security settings to take effect. Consider using IIS Authentication when: • You need restrict access to some of your sites resources. • You do not need to customize the logon screen. • Your users’ accounts are stored in valid Windows accounts. • You don’t mind the standard Windows logon screen.

IIS Authentication

Passport Authentication

Centralized authentication is a service provided by Microsoft that offers a single logon and core profile services for member sites. You should use passport authentication when your users require a single login to the asp.net applications that you develop. Also, if you do not wish to maintain user information, passport authentication has many options for gathering user profile type information.

Copyright ©2005 Global Knowledge Network, Inc. All rights reserved.

Page 13

You should consider Passport authentication when: • Your site will be used in conjunction with other Passport-enabled sites and you want to give single-sign-on capability to users accessing these sites. • You do not want to maintain a user name and password database. You should not consider Passport authentication when: • You want to exploit usernames and passwords already stored in your own database or Active Directory. (Although, with additional code, you can potentially map a Passport ID to a user account.) • Your clients are other computers that access the site programmatically.
Note: The Passport Authentication type uses the Windows Authentication provider.) Imagine that. : )

//Web.Config <system.web> <authentication mode="Passport"/> </system.web>

Forms authentication is a system by which unauthenticated requests are redirected to an HTML form using HTTP client-side redirection. The user provides credentials and submits the form. If the application authenticates the request, the system issues a form that contains the credentials or a key for reacquiring the identity. Subsequent requests are issued with the form in the request headers. They are authenticated and authorized by an ASP.NET handler using whatever validation method the application developer specifies. Use forms authentication when you want full control of your identity store. You should consider Forms authentication when: • User names and passwords are stored somewhere other than Windows Accounts. Note that it is possible to use Forms authentication with Windows Accounts. • You are deploying your application over the Internet. • You need to support all browsers and client operating systems. • You want to provide your own user interface form as a logon page.
Note: The Forms Authentication type uses the Forms Authentication provider.

Forms Authentication

//Web.Config <system.web> <authentication mode="Forms"/> </system.web>

Copyright ©2005 Global Knowledge Network, Inc. All rights reserved.

Page 14

You can use cookies with or without an authentication mechanism. Consider the following usage scenarios: • Use in conjunction with Forms authentication. The server issues the client with a cookie upon authentication and subsequent requests are verified based on the cookie presented to the server. • Use for personalization only, where customized content is provided to the user.

Custom Authentication

At some point you may discover that none of the available security providers meet your needs and that it may be necessary to create your own, so to speak. Well, that’s where custom authentication comes into play. You can create a custom solution using combinations of interfaces on the available providers or build a completely custom class to support authentication against your custom identity store or perhaps a custom interface to an existing identity store. For example, let’s say you would like to store users in Active Directory so that you can easily give them access to network resources and other applications already configured to use NTFS and folder-level permissions. You also have a requirement to place the company logo and a link to the privacy and security policy on the login page. You could build a custom authentication scheme that provides the user with the Login form required by your client while customizing the code to link to the active directory and then expose your new authentication provider though the authentication manager as a new authentication provider. There are many different ways to configure Authentication. Some are secure and some are not so secure. Choosing the right method of authentication can be driven by many factors from network infrastructure to developer skill. You also have legacy support issues. ASP.Net provides you with the tools to implement the Authentication scheme that is best suited to your project, while still allowing you the flexibility to expand and extend your existing architecture.

Summary

Learn More

Learn more about how you can improve productivity, enhance efficiency, and sharpen your competitive edge. Check out the following Global Knowledge courses: ASP.Net Web Programming .Net Fundamentals Microsoft MCAD Boot Camp Microsoft MCSD Boot Camp For more information or to register, visit www.globalknowledge.com or call 1-800-COURSES to speak with a sales representative. Our courses and enhanced, hands-on labs offer practical skills and tips that you can immediately put to use. Our expert instructors draw upon their experiences to help you understand key concepts and how to apply them to your specific work situation. Choose from our more

Copyright ©2005 Global Knowledge Network, Inc. All rights reserved.

Page 15

than 700 courses, delivered through Classrooms, e-Learning, and On-site sessions, to meet your IT and management training needs.

About the Author

Antoine Victor is a senior software developer with more than 10 years experience writing applications in various programming languages, including Visual Basic, AutoLisp, JavaScript, ASP, SQL, VB .NET, and C#. Working with many different clients, from small retail organizations to large government agencies such as the Federal Aviation Administration, Antoine has had the opportunity to develop many types of applications. They include document-management systems, e-commerce Web applications, inventory- and order-tracking systems, and disasterrecovery plans. At present, Antoine focuses on high-level consulting projects and spreading the .Net gospel through seminars and instructor-led training classes. Antoine is the co-founder of Professional Data Management. You cancontact him at [email protected]

Copyright ©2005 Global Knowledge Network, Inc. All rights reserved.

Page 16

Sponsor Documents

Or use your account on DocShare.tips

Hide

Forgot your password?

Or register your new account on DocShare.tips

Hide

Lost your password? Please enter your email address. You will receive a link to create a new password.

Back to log-in

Close