Sto tentando di accedere al mio server TFS al livello programmatico dall'esterno del dominio in cui è installato il server. Un programma di test di base sarebbe simile a questa:Accesso a livello di programmazione a TFS 2010 dall'esterno del dominio
class Program
{
static void Main(string[] args)
{
Uri tfsUri = new Uri("<serverUri>");
TfsConfigurationServer _ConfigurationServer = TfsConfigurationServerFactory.GetConfigurationServer(tfsUri);
CatalogNode projectCollectionCatalog = _ConfigurationServer.CatalogNode.QueryChildren(new[] { CatalogResourceTypes.ProjectCollection }, false, CatalogQueryOptions.None)[0]; // actual connection tries to happen here
}
}
Un'altra versione, con le credenziali forzata:
class Program
{
static void Main(string[] args)
{
Uri tfsUri = new Uri("<serverURI>");
TfsConfigurationServer _ConfigurationServer = new TfsConfigurationServer(tfsUri, new NetworkCredential("<DifferentKindOfUsernames>", "<Password>"));
CatalogNode projectCollectionCatalog = _ConfigurationServer.CatalogNode.QueryChildren(new[] { CatalogResourceTypes.ProjectCollection }, false, CatalogQueryOptions.None)[0];
}
}
Un'altra versione con un mix di entrambi versione precedente:
public class ConnectByImplementingCredentialsProvider : ICredentialsProvider
{
public ICredentials GetCredentials(Uri uri, ICredentials iCredentials)
{
return new NetworkCredential("<DifferentKindOfUsernames>", "<Password>", "<DomainOrNot>");
}
public void NotifyCredentialsAuthenticated(Uri uri)
{
throw new ApplicationException("Unable to authenticate");
}
}
class Program
{
static void Main(string[] args)
{
string _myUri = @"<serverUri>";
ConnectByImplementingCredentialsProvider connect = new ConnectByImplementingCredentialsProvider();
ICredentials iCred = new NetworkCredential("<DifferentKindOfUsernames>", "<Password>", "<DomainOrNot>");
connect.GetCredentials(new Uri(_myUri), iCred);
TfsConfigurationServer configurationServer =
TfsConfigurationServerFactory.GetConfigurationServer(new Uri(_myUri), connect);
configurationServer.EnsureAuthenticated();
}
}
e una versione con una directory attiva Impersonator:
class Program
{
static void Main(string[] args)
{
using (new Impersonator("<DifferentKindOfUsernames>", "<DomainOrNot>", "<Password>"))
{
Uri tfsUri = new Uri("<serverUri>");
TfsConfigurationServer _ConfigurationServer = TfsConfigurationServerFactory.GetConfigurationServer(tfsUri);
CatalogNode projectCollectionCatalog = _ConfigurationServer.CatalogNode.QueryChildren(new[] { CatalogResourceTypes.ProjectCollection }, false, CatalogQueryOptions.None)[0]; // actual connection tries to happen here
}
}
}
serverURI
sotto forma di http://<servername>:8080/tfs
o http://<serverip>:8080/tfs
(entrambi testati, con file host aggiornato) che è ciò che viene impostato come URL di notifica sul server TFS. Questo programma funziona all'interno del dominio.
DifferentKindOfUsernames
essere qualsiasi cosa da 'DOMINIO \ Nome utente', 'NomeDuplicato Locally', 'NomeUtente LOCALMACHINE' con la password appropriata, la password è la stessa nel dominio e sulla macchina.
Questo semplice l'accesso non funziona al di fuori del dominio, e non ho questo errore:
TF30063: You are not authorized to access <serverUri>
tradotto in un contesto web (utilizzando lo stesso processo in un sito asp.net), si tratta di un 401 errore:
The remote server returned an error: (401) Unauthorized.
anche se (cose testato finora):
- ho un mapping tra l'utente/password locale che gestiscono s il programma sulla macchina outsider di dominio e un account di directory attivo che ha accesso di amministratore a TFS (anche con i diritti di rappresentazione su TFS attivato).
- Aggiungo una chiave di registro
BackConnectionNames
con il nome del computer esterno del dominio e l'ip come descritto here. - Disabilito il controllo di loopback come descritto in here.
- Uso un identificatore di Active Directory con diverse combinazioni di utente/dominio o nome computer. Impersonator di Active Directory descritto here.
- Ho aggiunto l'IP del server TFS all'area Internet locale (provato anche come sito attendibile) nelle opzioni di sicurezza IE del server esterno del dominio come descritto in here.
Ho verificato l'accesso al serverURI da un browser. L'uri funziona e ho accesso alla collezione TFS se fornisco le credenziali con DomainName \ User + Password. Ho provato questo prima di qualsiasi delle modifiche che ho descritto prima. Mi chiedo quale potrebbe essere la differenza tra l'accesso programmatico e l'accesso al browser oltre a tutte le cose che ho testato finora.
Non si ha ancora accesso al server TFS dalla macchina su cui si sta eseguendo questo codice. È necessario verificare eventuali ulteriori impostazioni di sicurezza/autorizzazione all'interno di TFS. Non credo che questo sia un problema di programmazione. – qJake
@SpikeX: ho accesso al server TFS dalla macchina. Ho aperto le porte richieste e ho avuto accesso all'URI tramite un browser Web con le stesse credenziali che ho usato con un imitatore. Se il client web funziona, mi aspetto che il mio programma faccia lo stesso, ma non lo fa. Riesco a vedere le informazioni che dovrebbero essere recuperate dal mio programma se fosse in grado di connettersi (raccolta e elenco dei progetti). Posso capire perché è sfocato tra un errore di programmazione (inizializzazione di credenziali mancanti o errate) e un errore di rete/server (problema di configurazione). – Matthieu
Quindi la mia prossima domanda stupida è, il tuo URI contiene 'http: //' e un numero di porta, corretto? – qJake