What is TFS Impersonation?
TFS Impersonation is a feature that was introduced in TFS 2010 in order to allow a process running as User A to make web service calls to TFS in such a way that TFS thinks the actions are being performed by User B.
A long time ago, I wrote about Access Token With C#, a method that will allow you to perform actions with a different user.
Why? When writing Tools and services for customers, one of the most important features is to perform the action with the right user. Let’s say I want to run a service that for each Work Item Save action you want to add value to a field – this action is very simple but the history will show two actions from two different users, the user who runs the service did the action instead of the user who saved the work item.
And I can find couple more actions the Impersonation can help us with.
Step 1: Create Project and Add Reference
Create an WPF/WinForm application and add the following references:
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Framework.Client;
using Microsoft.TeamFoundation.Framework.Common;
using Microsoft.TeamFoundation.Server;
All files located under - c:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\ReferenceAssemblies\v2.0\
Step 2: Connect to Team Foundation Server
(TFS API Part 20: Bye TeamFoundationServer and Welcome TfsTeamProjectCollection)
TfsTeamProjectCollection tfs;
TeamProjectPicker tpp = new TeamProjectPicker(TeamProjectPickerMode.NoProject, false);
tpp.ShowDialog();
if (tpp.SelectedTeamProjectCollection != null)
{
tfs = tpp.SelectedTeamProjectCollection;
ims = tfs.GetService<IIdentityManagementService>();
GetUsers();
GetAuthenticatedIdentity(tfs);
}
Step 3: GetUsers & GetAuthenticatedIdentity
I’ve created the following methods to make things easier, GetUsers
will allow you to pick the user to Impersonate from the List instead of writing Account Names, etc. and GetAuthenticatedIdentity
will display the user running the TfsTeamProjectCollection
object.
void GetUsers()
{
IGroupSecurityService gss = (IGroupSecurityService)tfs.GetService(
typeof(IGroupSecurityService));
Identity SIDS = gss.ReadIdentity(SearchFactor.AccountName,
"Project Collection Valid Users", QueryMembership.Expanded);
Identity[] UserId = gss.ReadIdentities(SearchFactor.Sid,
SIDS.Members,QueryMembership.Expanded);
var query = from s in UserId
where s.Type == IdentityType.WindowsUser
select s;
UsersList.ItemsSource = query;
}
void GetAuthenticatedIdentity(TfsTeamProjectCollection current_tfs)
{
try
{
txt_current_user.Text = current_tfs.AuthorizedIdentity.DisplayName;
}
catch (AccessCheckException ex)
{
throw new AccessCheckException(ex.Message);
}
}
Step 4: Impersonate
public void Impersonation(Uri serverUri,string userToImpersonate)
{
TeamFoundationIdentity identity = ims.ReadIdentity(IdentitySearchFactor.AccountName,
userToImpersonate,
MembershipQuery.None,
ReadIdentityOptions.None);
tfs_impersonated = new TfsTeamProjectCollection(serverUri, identity.Descriptor);
GetAuthenticatedIdentity(tfs_impersonated);
}
Step 5: Enable “Make requests on behalf of others”
If you run the code right now – it will fail!
By default, the Administrators group does not have the "Make requests on behalf of others" permission.
To enable Impersonate, run the following command: tfssecurity.exe /collection:http://localhost:8080/tfs/DefaultCollection /a+ Server FrameworkGlobalSecurity Impersonate adm: ALLOW
After running the command, you should see “Make requests on behalf of others” enabled.
To disable Impersonate, run the following command:
tfssecurity.exe /collection:http://localhost:8080/tfs/DefaultCollection /a- Server FrameworkGlobalSecurity Impersonate adm: ALLOW
Now, after enabling Impersonation, you can use this tool:
Tfs object is now running using "Local Service"
Enjoy!