Я пытаюсь получить доступ к моему TFS-серверу программно из-за пределов домена, где установлен сервер.Базовая тестовая программа будет выглядеть так:
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();
}
}
И версия с активным каталогом Имитатор :
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
(оба проверены, с файлом hosts вверхна сегодняшний день), который установлен как URL-адрес уведомления на сервере TFS.Эта программа работает внутри домена.
DifferentKindOfUsernames
, что-то из 'DOMAIN \ Username', 'LocallyDuplicatedUsername', 'LOCALMACHINE \ Username' с соответствующим паролем, пароль одинаковый в домене и на компьютере.
Этот простой доступ не будет работать за пределами домена, и у меня есть эта ошибка:
TF30063: You are not authorized to access <serverUri>
переведено в веб-контексте (используя тот же процесс на веб-сайте asp.net), это ошибка 401:
The remote server returned an error: (401) Unauthorized.
, даже если (проверенные вещи):
- У меня есть сопоставление между локальным пользователем / паролем, который запускает программукомпьютер-аутсайдер домена и учетная запись активного каталога, у которого есть административный доступ к TFS (даже с активированными правами олицетворения для TFS).
- Я добавляю ключ реестра
BackConnectionNames
с именем компьютера-аутсайдера домена и ip, как описано здесь . - Я отключаю проверку петли, как описано здесь .
- Я использую имитатор Active Directory с различными комбинациямиser / домен или имя машины.Описанный имитатор Active Directory здесь .
- Я добавил IP-адрес TFS-сервера в локальную интернет-зону (также проверял доверенный сайт) в параметрах безопасности IE стороннего сервера домена, как описано здесь .
Я проверил доступ к serverURI из браузера.URI работает, и у меня есть доступ к TFS Collection, если я передаю учетные данные с помощью DomainName \ User + Password.Я проверял это перед любой из модификаций, которые я описал ранее.Интересно, в чем может быть разница между программным доступом и доступом к браузеру, кроме всего того, что я до сих пор тестировал.