0
votes

So i'm trying to develop a web app (c#, asp.net 4.5) that uses windows identity and also impersonation to connect to TFS(team foundation server) and retrieves some elements (work items, tasks, etc). The problem is that impersonation works only on the server where the app runs, as in only for my identity. Whenever anyone else tries to connect, their access is denied, app crashes an unauthorized error " TF30063: You are not authorized to access [server address]". Surely the other persons are authorized because they can access TFS directly (not through my app, however) and some of them are administrators.

The stretch of code that returns the error is this one

 protected TfsTeamProjectCollection TeamProjectCollection
        {
            get
            {
                if (tpc == null)
                {
                  // I HAVE ALSO TRIED THIS COMMENTED OUT PART, TOO. Still doesn't work.
                  //  using (WindowsIdentity.GetCurrent().Impersonate())
                  //  {
                  //    tpc = new TfsTeamProjectCollection(new Uri(ConnectionString));
                  //  }
                        var identityDescriptor = Microsoft.TeamFoundation.Framework.Client.IdentityHelper.CreateDescriptorFromSid(WindowsIdentity.GetCurrent().User);
                        tpc = new TfsTeamProjectCollection(new Uri(ConnectionString), identityDescriptor);
                }
                return tpc;
            }
        }

Has anyone else encountered this before? I've spent days researching the web but haven't found an answer that works. Hope you guys can help! Other mentions: in web.config i have set " identity impersonate = true", in iis i have enabled asp.net impersonation and windows authentication. all other auth options are disabled.

2
I think you need to use HttpContext.Current.User.Identity instead of WindowsIdentity.GetCurrent().Martin Liversage
No, sorry. I wish it were that simple. You can't pass httpcontext.cu... to the descriptor. It takes a parameter that must be a sid, so that is not a valid type. Just tried this. Thanks anyway.Alex Serban
I didn't provide a proper answer because I'm not sure about the details. However, I'm pretty sure that WindowsIdentity.GetCurrent() is the identity used to by the IIS worker process which is a service account and not what you want to use when accessing TFS. HttpContext.Current.User.Identity provides you with the identity of the current user (the user at the browser) and you need to translate this into the desired form for use by TFS in some way. If you need a SID and only have a user name like DOMAIN\USER you need to map that user name to a SID in your code.Martin Liversage

2 Answers

0
votes

I'm using this piece of code for impersonating in a WCF service:

/// <summary>
/// Impersonation - Creates new instance of TfsTeamProjectCollection object using a different user;
/// </summary>
/// <param name="serverUri">Tfs server uri you want to connect using Impersonation</param>
/// <param name="userToImpersonate">Account name of the user you want to Impersonate</param>
private void Impersonation(Uri serverUri, string userToImpersonate)
{
    try
    {
        eventLog1.WriteEntry("Start Impersonation");
        // Read out the identity of the user we want to impersonate
        TeamFoundationIdentity identity = ims.ReadIdentity(IdentitySearchFactor.AccountName,
            userToImpersonate,
            MembershipQuery.None,
            ReadIdentityOptions.None);
        eventLog1.WriteEntry(identity.DisplayName);
        this.impersonatedTFSUser = new TfsTeamProjectCollection(serverUri, identity.Descriptor);
        eventLog1.WriteEntry(impersonatedTFSUser.Name);
        eventLog1.WriteEntry("End Impersonation");
    }
    catch (Exception ex)
    {
        throw ex;
    }
}
0
votes

Solved this with some help. So the fact is that if i use TFS impersonation, the app pool needs to run with a user that has access to TFS and not much more than this. I disabled asp.net impersonation, and only enabled Windows Auth. Also i changed the "Identity" from the app pool advanced settings to my TFS user. Now there is another problem. Anyone who uses the web app is only able to see the projects that both him and my user have rights to. Also, when saving a work item, TFS autocompletes the "created by" field with the app pool identity (my user, in this case) and the "Last modified" with the user that runs the app. That's not how i want it to work so i'm going to do some more research.