Customize Team Build 2010 – Part 9: Impersonate activities (run under other credentials)

by Ewald Hofman 27. May 2010 22:25

In the series the following parts have been published

  1. Part 1: Introduction
  2. Part 2: Add arguments and variables
  3. Part 3: Use more complex arguments
  4. Part 4: Create your own activity
  5. Part 5: Increase AssemblyVersion
  6. Part 6: Use custom type for an argument
  7. Part 7: How is the custom assembly found
  8. Part 8: Send information to the build log
  9. Part 9: Impersonate activities (run under other credentials)
  10. Part 10: Include Version Number in the Build Number
  11. Part 11: Speed up opening my build process template
  12. Part 12: How to debug my custom activities
  13. Part 13: Get control over the Build Output
  14. Part 14: Execute a PowerShell script
  15. Part 15: Fail a build based on the exit code of a console application
  16. Part 16: Specify the relative reference path

 

 

Update: If you want to use the TFS Object Model in the activity code, check the following post: http://blogs.msdn.com/b/taylaf/archive/2009/12/04/introducing-tfs-impersonation.aspx. It gives you the ability to execute TFS request on behalf on someone else without providing a password.

There are situation in which you want to run your activity under other credentials, which is also called impersonation. This could be the case for example when you deploy your solution to the development environment.

To achieve the impersonation of the an activity we need to be able to specify the credentials in an argument of the build. Because you don’t want that the password is visible, we need to specify a custom type. This process is covered in Customize Team Build 2010 – Part 6: Use custom type for an argument.

Secondly we need to impersonate. To achieve this I create a class with that logs on as a different user in the constructor and in the destructor (dispose method) the user is logged off again.

using System.Runtime.InteropServices;
using System.Security.Principal;
using System;
using Achmea.Build.Tasks.CustomType;

namespace Achmea.Build.Tasks.Library
{
    public class Impersonation : IDisposable
    {
        private WindowsImpersonationContext _impersonatedUser = null;
        private IntPtr _userHandle;

        public Impersonation(Credential credentials)
        {
            if (credentials != null && !string.IsNullOrEmpty(credentials.UserName))
            {
                _userHandle = new IntPtr(0);

                bool returnValue = LogonUser(credentials.UserName, credentials.Domain, credentials.Password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref _userHandle);

                if (!returnValue)
                    throw new ApplicationException("Could not impersonate user");

                WindowsIdentity newId = new WindowsIdentity(_userHandle);
                _impersonatedUser = newId.Impersonate();
            }
        }

        #region IDisposable Members

        public void Dispose()
        {
            if (_impersonatedUser != null)
            {
                _impersonatedUser.Undo();
                CloseHandle(_userHandle);
            }
        }

        #endregion

        #region Interop imports/constants
        public const int LOGON32_LOGON_INTERACTIVE = 2;
        public const int LOGON32_LOGON_SERVICE = 3;
        public const int LOGON32_PROVIDER_DEFAULT = 0;

        [DllImport("advapi32.dll", CharSet = CharSet.Auto)]
        public static extern bool LogonUser(String lpszUserName, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        public extern static bool CloseHandle(IntPtr handle);
        #endregion
    }
}

You can now easily impersonate an activity by surrounding the code of the activity by constructing the Impersonation class in the first line, and dispose it at the last line. In C# you can make it even easier when you use the “using” statement

using System.Activities;
using Achmea.Build.Tasks.CustomType;
using Achmea.Build.Tasks.Library;
using Microsoft.TeamFoundation.Build.Client;

namespace BuildTasks.Activities
{
    [BuildActivity(HostEnvironmentOption.Agent)]
    public class CopyFile : CodeActivity
    {

        public InArgument<Credential> Credentials { get; set; }

        protected override void Execute(CodeActivityContext context)
        {
            using (Impersonation impersonation = new Impersonation(context.GetValue(this.Credentials)))
            {
                // Insert your activity code over here
            }
        }
    }
}

 

You can download the full solution at BuildProcess.zip. It will include the sources of every part and will continue to evolve.

Tags:

Team Build | VSTS 2010

Comments

11/9/2010 5:32:35 AM #

trackback

Part 14: Execute a PowerShell script

Part 14: Execute a PowerShell script

Ewald Hofman |

12/13/2010 7:31:07 AM #

Jeff

The impersonate does not seem to work if you run a bat file within the impersonate.

social.msdn.microsoft.com/.../e03174c2-c5cf-468b-8178-623ddc570656

Any thoughts?

Jeff

Jeff United States |

12/15/2010 6:39:16 AM #

Ewald Hofman

I saw your post on the MSDN Forums and your analysis is correct in that post that you only impersonate the code that you are executing.

I have no other thoughts how you can solve this. Sorry.

Ewald Hofman Netherlands |

5/31/2011 8:22:12 AM #

trackback

Ewald’s posts on TFS Build 2010

Ewald Hofman , an ALM MVP, has written a great series of blog posts on Team Build in Team Foundation Server 2010.  The 2010 release introduces Windows Workflow as the overall orchestrator of the build process.  Ewald walks you through quite a few topics related to this and the other new features.  Check it out! Part 1: Introduction Part 2: Add arguments and variables Part 3: Use more complex arguments Part 4: Create your own activity Part 5: Increase AssemblyVersion Part 6: Use custom type for an argument Part 7: How is the custom assembly found Part 8: Send information to the build log Part 9: Impersonate activities (run under other credentials) Part 10: Include Version Number in the Build Number Part 11: Speed up opening my build process template Part 12: How to debug my custom activities Part 13: Get control over the Build Output Part 14: Execute a PowerShell script Part 15: Fail a build based on the exit code of a console application Part 16: Specify the relative reference path Technorati Tags: tfs 2010 , team build , windows workflow

Buck Hodges |

Comments are closed

Powered by BlogEngine.NET 1.6.1.0
Theme by Mads Kristensen


ClusterMap

Statistics

Statistics created at 09 Sep 2009

121 posts
487 comments
316 raters
1762642 visit (1044 per day)
18 users online

Recent comments

Comment RSS