Impersonation

Impersonation is a way to programmatically log on as a user who is different from the actual physical user. In the context of CMS, there are a few reasons why you might want to implement this feature. For example, let's suppose that the current user is an author and you would like to give them the ability to create a channel. The only sure way to provide them with this functionality is to make them a channel manager or an administrator. Obviously, this route is not always the best one and it tends to be unilateral yes, you've given them the ability to create channels, but you've also provided them with certain authority over security, channel properties, and content approval. This is not ideal. So, the real answer to the problem is impersonation.

Essentially, it is possible to programmatically and temporarily log on as a generic, impersonated user with certain rights in this case as either an administrator or a channel manager perform the operation you need to perform, and log that generic user out.

The first step is defining what functionality you would like to expose. Building off of the example we provided earlier, let's suppose that BOTS Consulting wants to give their editors the ability to create new channels in the Knowledge section so that it's possible for editors to create new classifications of "knowledge" as the firm changes over time. Since editors don't inherently have this ability, you'll first need to create a user ID under which this operation can be performed. In this example, we've created a generic user called IMPCHANNELADMIN. This user is defined as a channel manager in the Knowledge section.

NOTE: You could also create an administrator-level account, but since the requirement was specific to the Knowledge section, we didn't want to give the impersonated user too much power. The choice is up to you.


The next step is to create an interface that allows the editor to provide the channel properties for the new channel (see Figure 36-3). In this example, you need to create a form that allows the editor to enter the name and display name for the new channel.

Figure 36-3. Sample interface for a channel creation tool

graphics/36fig03.gif

Once the interface is defined, you need to add the code to support the operation. In this case, the form will allow the user to enter the properties and, on postback, log on as the generic administrator, create the channel, and return a success or failure message. In Listing 36-2 you will see a rough sample of how to create the impersonation logic.

Listing 36-2 Creating a Web-based channel creation solution using impersonation

[View full width]

 private void Page_Load(object sender, System.EventArgs e) {       try       {             // Show the current user             this.CurrentUser.Text = CmsHttpContext.Current.User. ServerAccountName;             // Set parent channel from the query string             // We assume that you would create a link from a posting in the             // site to this page, enabling the user to create a channel.             // When you call the page, you provide the current channel's path             // as a query string parameter.  You could equally pass the             // parent's GUID.             if (Request.Params["ParentChannel"] != null)             {                   this.txbParentChannel.Text = Request.Params ["ParentChannel"];                   // Create a reference to the channel                   Channel objParentChannel = (Channel)CmsHttpContext.Current. Searches graphics/ccc.gif.GetByPath(this.txbParentChannel.Text);                   // Make sure the channel exists                   if (objParentChannel == null)                   {                         this.DisplayNonExceptionMessage("The specified channel does not graphics/ccc.gif exist.");                   }             }             else             {this.DisplayNonExceptionMessage("No parent channel specified");}       }       scatch(Exception eException)       {             this.DisplayExceptionMessage(eException);       } } public CmsApplicationContext AuthenticateasAdminUser() {       CmsApplicationContext newContext = new CmsApplicationContext();       newContext.AuthenticateAsUser("WinNT://cmsdemo1/cmsadmin","password", PublishingMode graphics/ccc.gif.Update);       return newContext; } private void CreateNewChannel (CmsApplicationContext myContext) {       try       {             // Create a channel object representing the parent channel             Channel objParentChannel = (Channel)myContext.Searches.GetByPath(this graphics/ccc.gif.txbParentChannel.Text);             // Create the new channel, assign the name and displayname             // properties as provided by the user and commit the transaction             Channel objNewChannel = (Channel)objParentChannel.CreateChannel();             objNewChannel.Name = this.txbName.Text.ToString();             objNewChannel.DisplayName = this.txbDisplayName.Text.ToString();             myContext.CommitAll();             this.DisplayNonExceptionMessage("New channel created successfully.");       }       catch(Exception eException)       {             this.DisplayExceptionMessage(eException);       } } private void DisplayExceptionMessage(Exception eException) {       this.lblMessage.Text = "An exception occurred:<br>Message: "             +eException.Message.ToString()+"<br>Source: "+eException.Source; } private void DisplayNonExceptionMessage(string strMessage) {       this.lblMessage.Text = strMessage; } private void btnCreateChannel_Click(object sender, System.EventArgs e) {       CreateNewChannel(AuthenticateasAdminUser()); } 

In our example, we clearly broke some basic rules of security by embedding the user ID and password in the code. Keep in mind that this is just a sample. The overall concept, however, could be useful in extending the Web Author to allow a moderated ability to expand the structure of your site. A variation on this code could be a check to see what role the user occupies and to limit the channel creation ability to editors instead of everyone. Also, we're using the CmsApplication Context object for a few reasons:

  • It allows us to authenticate inline without having to set a cookie and redirect.

  • We leave the existing user's credentials intact on their machine.

  • We can use this method whether or not we're using Forms or Windows authentication.

If you are using Forms authentication and you want to log the current user out, log your impersonated user in, perform the operation, and then log the original user back in, it's possible to do that with CmsForms Authentication. We found our methodology easier, though, since you don't have to worry about persisting the current user's credentials somewhere.



Microsoft Content Management Server 2002. A Complete Guide
Microsoft Content Management Server 2002: A Complete Guide
ISBN: 0321194446
EAN: 2147483647
Year: 2003
Pages: 298

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net