An Impersonation Web Application

Jim Corbin has passed along this great post:

When you impersonate a user in an application for Project Server 2007, you adopt the global and category permissions of the impersonated user. This article shows how to develop a Web application for Project Server that uses impersonation. The attached pj12Impersonation.zip file includes a complete Web application that allows you to log on Project Server using Forms or Windows authentication, checks your permissions for listing and creating projects, and then lets you impersonate any other Project Server user.

Important: The Impersonation Web application is an example for demonstration purposes only. The application is designed to run on a test installation of Project Server. It allows anyone with a Project Server account to log on, impersonate any other user, and create projects. To use any impersonation application on a production server, you must programmatically limit usage and add security checks that are appropriate for your organization.

Most applications for Project, including Project Professional 2007 and Project Web Access, call the Project Server Interface (PSI) Web services through the Project Web Access URL. Project Server enforces the security permissions of your account when you log on through an application that uses the Project Web Access URL. Impersonation requires direct calls to the PSI through the Shared Service Provider (SSP) Web application that hosts Project Web Access.

The Project 2007 SDK includes the section Using Impersonation in Project Server with the article How to Write a Simple Impersonation Application. The ProjTool application in the SDK download also uses impersonation.

The following figure shows the Impersonate page in the Web application, which indicates the identity of the application user. The application user can log on Project Server using Windows authentication; in the figure, the user has clicked Forms for the Authentication Type and logged on a Project Server user named Joe. Joe has the NewProject global permission to create a project, but is denied the ManageQueue permission necessary to execute the ReadProjectList PSI method. If you (as the application user) select Joe in the Select User drop-down list and then click Impersonate, you would run the application with Joe’s permissions. If you click List Draft Projects, the application would return an exception because Project Server does not allow Joe to use ReadProjectList. If you check the Use ReadProjectStatus() checkbox while impersonating Joe, the application would call the ReadProjectStatus method instead, and Joe could get the list of draft projects.

In the figure, the logged-on user Joe is impersonating the Administrator user, who does have the ManageQueue permission. Therefore, Joe can use the ReadProjectList method even though his own account does not have permission to do so. The application also enables an impersonated user (who has the NewProject permission) to create and publish a project, and then shows the new project in the list. The Draft Projects grid shows up to six projects and dynamically creates additional grid pages as needed.

To install the Impersonation Web application:

1. Create a directory for the source files on your test Project Server computer, for example, C:\Project\.

2. Unzip all of the files in pj12Impersonation.zip to C:\Project\. The top-level folder in the zip file is named Impersonation, so the local directory for the Web application is C:\Project\Impersonation.

3. Using Internet Information Services (IIS) Manager on your Project Server computer, create a top-level Web site named, for example, Impersonation. Use the local path you created in Step 1 (C:\Project\Impersonation). Allow script access and executables. Disable anonymous access (use Integrated Windows Auth only). The Impersonation Web site can't be a SharePoint site, so set the port to something besides the ports that Project Web Access and Windows SharePoint Services use, such as 5636. Project Web Access typically uses port 80 for Windows authentication and port 81 for Forms authentication. Your Impersonation site URL would therefore be the following:

https://ServerName:5636

4. The Impersonation Web site needs to run under a service account that is trusted by Project Server. Create a new application pool in IIS, for example, ImpersonationAppPool. On the Identity tab of the ImpersonationAppPool Properties dialog box, set the Configurable property of the Application Pool Identity to the same user account and password for the Project Web Access site administrator. To find the user account for configuring Project Web Access, do the following:

a. Open the SharePoint 3.0 Central Administration site, and click Application Management.

b. On the Application Management page, click Create or configure this farm’s shared services.

c. Click the name of the SSP where Project Web Access is installed. For example, click SharedServices1 (Default) .

d. On the Home page of the Shared Services Administration site, click Project Web Access Sites.

e. On the Manage Project Web Access Sites page, pause the mouse pointer over the site instance you want, click the down-arrow, and then click Edit.

f. On the Edit Project Web Access Site page, use the value in the Administrator Account text box. For example, set the Application Pool Identity to domain\pwaAdminName.

5. In IIS Manager, right-click the Impersonation Web site, click Properties, and then click the Home Directory tab. Set the Application pool value to the ImpersonationAppPool you created in Step 4.

6. On the Impersonation Web site Properties page in IIS, click the ASP.NET tab, and then set the ASP.NET version to 2.0.50727.

7. In IIS Manager, right-click the local computer name, and then click Properties. Click Enable Direct Metabase Edit. Then use Notepad to open the metabase.xml file in %systemroot%\system32\inetsrv. Search for the site name within an IISWebServer tag. Add the attribute NTAuthenticationProviders="NTLM”. For example, following is the complete element for the new Impersonation site.

<IIsWebServer Location ="/LM/W3SVC/784768436"

            AuthFlags="0"

            NTAuthenticationProviders="NTLM"

            ServerAutoStart="TRUE"

            ServerBindings=":5636:"

            ServerComment="Impersonation"

      >

</IIsWebServer>

8. Restart IIS.

9. Copy the following files to the Bin subdirectory in the Impersonation Web site:

· Microsoft.Office.Project.Server.Library.dll (copy from C:\Program Files\Microsoft Office Servers\12.0\Bin)

· Microsoft.SharePoint.dll (copy from C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\ISAPI)

· Microsoft.SharePoint.Search.dll

10. Start Visual Studio 2005, and then open the Impersonation Web site from the Local IIS. When you click Save All, save the solution file as Impersonation.sln in C:\Project\Impersonation, for easy access.

11. The Web application needs the same validation key that Project Web Access uses for calling the PSI. The <machineKey> element in web.config sets keys to use for encryption and decryption of Forms authentication cookie data. The <machineKey> element allows developers to configure a validation key that performs message authentication checks on Viewstate data and Forms authentication tickets. <machineKey> can be declared at the computer, site, or application levels, but not at a subdirectory level . If you don't specify the correct <machineKey> attributes, then you get a Viewstate error.

Set the <machineKey> attributes for your Project Server computer in web.config for the Impersonation site. Copy the complete <machineKey ...> line from the web.config file in your top-level site for Project Web Access (typically the default Web site), and replace the <machineKey … > line in the web.config file of the Impersonation site. The element should be all on one line, and a child of the <system.web> element, for example:

<machineKey validationKey="7C9DF8E41A03170EFF870936E0FED824859E541C6CF5768F" decryptionKey="EAAECB67BFF6AED2F4F812ADE1967CB6AB33A94A9FDE400C" validation="SHA1" />

12. In the App_Code subdirectory, the Global.asax.cs file has all of the Application_Start, etc., methods that normally are in Global.asax. There’s no particular reason that Global.asax.cs is in App_Code, except that is where Visual Studio prefers to put it. You could put Global.asax.cs under Global.asax, if you add the following attribute to the Application directive in Global.asax:

CodeBehind="Global.asax.cs"

13. In ImpersonationUtils.cs, change the SERVER_NAME constant to use your server name. Change the name of the Shared Service Provider (SSP) from SharedServices1 to the correct name for your SSP, and change the SSP port value if necessary. Build the Web site.

14. Your Impersonation Web site should now work. Test the site on the local Project Server computer and on a remote computer. If the Impersonation application works on the local Project Server computer but not on a remote computer, it is likely that the IISWebServer tag (Step 7) is not correct. If you get an HTTP 401 (unauthorized) exception when you first try to log on with a Windows account, check that the application pool owner is set properly (Step 4).

When you log on Project Server with the Impersonation application, calls to the PSI use PROJECT_SERVER_URI for the value of the ResourceDerived.Url property. For Forms logon, the application sets the Url property to PROJECT_SERVER_FORMS_URI. During impersonation, the application sets the Url property to SSP_URI, for PSI calls to the ProjectDerived and SecurityDerived objects.

There are comments in the code that explain several parts of the application. For an explanation of the proxy and derived classes for the PSI Web services, see How to: Write a Simple Impersonation Application in the Project 2007 SDK. The logon routines in the ImpersonationUtils.cs file are based on code in the ProjTool sample; for more information, see Using the ProjTool Test Application.

pj12Impersonation.zip