2011-09-29 1 views
6

Я пытаюсь получить доступ к своему серверу TFS программно из-за пределов домена, где установлен сервер. Основная тестовая программа будет выглядеть следующим образом:Программный доступ к TFS 2010 за пределами домена

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 
     } 
    } 

другой версии, с учетными данными вынужденную:

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]; 
     } 
    } 

Другой вариант с сочетанием обоих предыдущей версии:

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(); 


     } 
    } 

и версия с активным справочником 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 находится в форме http://<servername>:8080/tfs или http://<serverip>:8080/tfs (оба протестированы, с обновленными файлами хостов), что соответствует URL-адресу уведомлений на сервере TFS. Эта программа работает внутри домена.

DifferentKindOfUsernames есть что-либо из «ДОМЕНА \ Имя пользователя», «ЛокальноДублица», «LOCALMACHINE \ Username» с соответствующим паролем, пароль тот же в домене и на машине.

Этот простой доступ не будет работать за пределами домена, и у меня есть эта ошибка:

TF30063: You are not authorized to access <serverUri> 

переведенный в веб-контексте (используя тот же самый процесс в веб-сайт asp.net), это 401 ошибка:

The remote server returned an error: (401) Unauthorized. 

даже если (вещи проходят до сих пор):

  • у меня есть отображение между локальным пользователем/пароль, которые управляют s программа на машине постороннего домена и активная учетная запись каталога, у которой есть доступ администратора к TFS (даже с правами на олицетворение при активации TFS).
  • Я добавляю ключ реестра BackConnectionNames с именем машиниста домена и ip, как описано here.
  • Отключить проверку петли, как описано here.
  • Я использую Император Active Directory с различной комбинацией имени пользователя/домена или имени машины. Описание Имперсонатора Active Directory here.
  • Я добавил IP-адрес сервера TFS в локальную интернет-зону (также проверенный доверенный сайт) в настройках безопасности IE сервера аутсайдера домена, как описано here.

Я протестировал доступ к серверуURI из браузера. Ури работает, и у меня есть доступ к коллекции TFS, если я даю учетные данные с DomainName \ User + Password. Я тестировал это перед любыми изменениями, которые я описал ранее. Интересно, какая разница между программным доступом и доступом к браузеру, помимо всего, что я тестировал до сих пор.

+0

У вас до сих пор нет доступа к серверу TFS с компьютера, на котором вы сейчас запускаете этот код. Вам нужно проверить дополнительные настройки безопасности/разрешения в TFS. Я не считаю, что это проблема программирования. – qJake

+0

@SpikeX: У меня есть доступ к TFS-серверу с компьютера. Я открыл необходимые порты и получил доступ к URI через веб-браузер с теми же учетными данными, которые я использовал с Impersonator. Если веб-клиент работает, я ожидаю, что моя программа сделает то же самое, но это не так. Я могу просмотреть информацию, которая должна быть получена моей программой, если она сможет подключиться (Collection and Project List). Я могу понять, почему он размывается между ошибкой программирования (отсутствием или неправильной инициализацией учетных данных) и ошибкой сети/сервера (проблема с конфигурацией). – Matthieu

+0

Тогда мой следующий глупый вопрос: ваш URI содержит 'http: //' и номер порта, правильно? – qJake

ответ

4

Вы не передаете учетные данные для создания соединения. Это означает, что вы используете ваши учетные данные, которые вы уже ввели в систему, с хоста вне домена.Я не эксперт по проверке подлинности Windows, но я думаю, что это может при определенных обстоятельствах работать прозрачно (если имя пользователя и пароль идентичны), но, похоже, зависит от используемой версии NTLM, операционных систем клиента и сервера , доверительные отношения и зоны безопасности, конфигурацию IIS и, возможно, фазу луны.

Другими словами, вы, вероятно, хотите, чтобы передать полномочия на соединение:

TfsConfigurationServer _ConfigurationServer = new TfsConfigurationServer(uri, new NetworkCredential("username", "password", "DOMAIN")); 

Обратите внимание, что настоятельно рекомендуется включить SSL/TLS, если вы подключаетесь к серверу через ненадежный (публичное) сеть.

(я исправил это использовать три-Arg конструктор NetworkCredential -. Моя ошибка Как вы обратите внимание, если вы поставите DOMAIN\username в имя пользователя аргумент NetworkCredential, он будет относиться к ней как \DOMAIN\username вместо DOMAIN\username Это, я. предположим, это почему никто не позволяет мне писать код C#.)

+0

Все еще не работает. Существует много способов олицетворять пользователя для TFS, и я проверил несколько из них без успеха. Это дает ту же самую ошибку TF30063. Я обновлю свой вопрос, чтобы представить другую версию кода, который я тестировал до сих пор. – Matthieu

+0

Спасибо за редактирование, это намного яснее. Из любопытства, что произойдет, если вы вызываете tfs.ensureAuthenticated() вместо того, чтобы пытаться запросить данные каталога? Я предполагаю, что вы все еще получаете ошибку? –

+0

Да Это та же ошибка. Я занимаюсь анализом сети. Я отвечу на ваш комментарий с результатом. – Matthieu