Logon with the object model in RC

In beta 3 I used a NetworkCreditials object to create a conenction to a TFS server.  

NetworkCredential objNetworkCredential = new NetworkCredential(strUserName, strUserPassword, strDomain);

TeamFoundationServer objTFS = TeamFoundationServerFactory.GetServer(strVstsURL, objNetworkCredential);

But in the RC version the factory uses a Microsoft.TeamFoundation.Client.ICredentialsProvider in the GetServer method.

In Client applications I can used the UICredentialsProvider, but what about Server applications

Is the only way to logon to a TFS server in server application to use the current users credentials

 

Regards

Christian

 

 

 



Answer this question

Logon with the object model in RC

  • Batool

    I am having a problem connecting to TFS in an IIS app. When running in a simple C# form executing as my domain account (which is in the TFS admin group) everything authenticates fine. I can also change the "NetworkCredential" to other user accounts that have TFS permissions.

    However, when running under an IIS application, with the application pool running as NetworkService I cannot authenticate any user accounts and a "TF30076: The server name [ServerName] provided does not correspond to a server URI that can be found. Confirm that the server name is correct." error is thrown. If I change the application pool identity to run as my domain account, again everything runs fine and I can authenticate via my account or other user accounts as specified via the NetworkCredential class.

    The code used is:

    NetworkCredential objNetworkCredential = new NetworkCredential(UserName, UserPassword, UserDomain);
    tfs = new TeamFoundationServer(ProviderPath, objNetworkCredential);
    tfs.Authenticate();

    Any guesses Thanks in advance,

  • Basic

    Hi,

    Can you try the following:

    1) Create a local user on the machine where you have deployed your IIS app and add this user to IIS_WPG and local Administrators group

    2) Set the AppPool Identity for your app as this local user

    3) Run IISRESET and try executing your app

    The above settings works for me in a sample web app that uses TFS RTM version

    Swamy



  • wantowan2

    Right, all of the samples that were written in the beta 3 time frame had to do that. I may go back and update them.

    Buck



  • axdimensions

    You could directly use the constructor of the TeamFoundationServer object and pass in the objNetworkCredential object:

    TeamFoundationServer objTFS = new TeamFoundationServer("name", objNetworkCredential)

    Cheers



  • greenhorn

    Thanks :-)

    I was so focused on the factory, that I never looked at the constructor

    Christian


  • Bomy

    Buck,

    Thanks for your guidance. This looks like it meets my needs.

    Interestingly, I believe I started out using the factory after reading an example on your blog. :-)


  • Paul Monson

    Hi Swamy,

    I get the same error stated before with these steps. BTW, I am currently running the RC version.

    I AM able to get it to work if I log into the machine with the app pool identity account, run Team Explorer, connect to the TFS server, and reset iis. It seems like it is using some cache within LocalSettings of the executing account to connect... At least this is somewhat of a workaround.


  • Dogu

    Buck,

    I need to cache/test credentials for later command line client scripting. This method appears to work:

    public bool TestConnection(string serverName, string domain, string userName, string password)
    {
    NetworkCredential credentials = new NetworkCredential(userName, password, domain);

    TeamFoundationServer tfServer = TeamFoundationServerFactory.GetServer(serverName, credentials);

    try
    {
    tfServer.Authenticate();
    }
    catch { }

    return tfServer.HasAuthenticated;
    }


    I am concerned because System.Net.NetworkCredential does not implement ICredentials and the docs list the signature for this overload as:
    public static TeamFoundationServer GetServer( string name, ICredentials credentials );

    Am I missing something


  • maciu

    Buck,

    This no longer works in the RC. The overload which allows passing ICredentials is not there in the RC.

    The only overloads available for GetServer() are:
    public static TeamFoundationServer GetServer( string name, ICredentialsProvider credentialsProvider );

    public static TeamFoundationServer GetServer( string name );

    So much for the go-live license. The guidance since Tech-Ed 2005 has been to write to the object model rather than talking directly to the web services. If I had ignored that advice, I would not have to cancel my demo tomorrow.

    <flame>THIS IS NOT COOL!</flame>

    How do you recommend that I work around this issue, and can you give any reason for removing the overloads to GetServer() between Beta3 and RC

    ++Alan


  • Wallsatlarge

    The credentials parameter for the factory methods resulted in lots of confusion about what it meant and how it was handled.

    The only thing the factory really does is maintain a hash table of TeamFoundationServer objects, keyed by a server identifier.

    Here's an example of one way you might go about it.

                    Dictionary<string, TeamFoundationServer> serverCache =
                        new Dictionary<string, TeamFoundationServer>(StringComparer.InvariantCultureIgnoreCase);

                    // Get the instance from the cache if we have one.
                    TeamFoundationServer tfs;
                    if (serverCache.TryGetValue(serverName, out tfs))
                    {
                        return tfs;
                    }

                    tfs = new TeamFoundationServer(name, new NetworkCredentials(userName, password, domain));
                    serverCache[serverName] = tfs;

                    tfs.Authenticate();

    Buck



  • alex2000

    Alan, the code you have written will work correctly, so long as you don't ask for a reference to the same server but with different credentials.  The way the factory works is that it keeps a hash table with the TeamFoundationServer objects keyed by URI.  Whenever GetServer() is called, it first checks to see whether an existing TeamFoundationServer object with the same server URI is already in the hash table.  If there is a matching object, it returns it.  It intentionally does not consider whether the credentials match or not.  The reason for that is that it was designed to support the needs of VS or another similar app where a plugin can get the same TeamFoundationServer object as another, without having to know the credentials.

    So, in your case, you'll need to evaluate whether you need to have multiple instances of TeamFoundationServer that have different credentials.  If the answer is yes, you'll want to use the constructor rather than the factory and manage the objects in a way that makes sense based on the design of your application.

    NetworkCredential does indeed implement ICredentials, as does CredentialCache.  If you are curious, you can find more details about credential objects at http://blogs.msdn.com/buckh/archive/2004/07/28/199706.aspx.

    Buck



  • Darryl Thompson

    Well, I checked help again and it said:

    public class NetworkCredential : ICredentials, ICredentialsByHost

    I swear that wasn't there on Friday. :-D

    Your guidance on using the factory is interesting, and confirms that it is the correct approach to my client-only app.

    The only wrinkle I have now with authentication is that clients aren't part of the same domain as the TFS. Therefore, they can authenticate using my app without explicitly declaring the domain, but the command line client requires that I explicitly declare the domain as part of the credentials.

    Users have identical username/password on their workstations, but the workstations are not part of the domain. Any suggestions


  • Gerald12345

    Chandru is correct. In beta 3, the constructor for TeamFoundationServer was not public, though it had been in prior releases. The factory class is not suitable when you want to manage tfs objects with different credentials, so it's best to use the constructor.

    Buck



  • Dave19

    When calling tfs = new TeamFoundationServer(ProviderPath, objNetworkCredential); what value were you passing to ProviderPath

    If you were passing just the "ATServerName" can you try passing http://ATServerName:8080

    Also in my case NetworkService (as AppPool identity) works if I add NetworkService to local administrators group

    Swamy



  • Logon with the object model in RC