首页 > 解决方案 > 尝试在 Windows 10 上配置 TFS 代理时出错

问题描述

我有一个自托管 TFS,我正在尝试在 Windows 10 机器上为其配置代理。我运行配置脚本。我输入我的 TFS 实例的 URL,并选择默认身份验证类型。该脚本尝试连接,但返回错误消息:“TFS 资源不可用于匿名访问。需要客户端身份验证。”

我可以通过网络浏览器访问我在脚本中输入的 URL,因此我知道机器可以访问它。我使用 fiddler 来监控流量,而脚本正在尝试连接到 URL。Fiddler 显示了脚本尝试连接的 URL (http://{mydomain}/_apis/connectionData?connectOptions=1&lastChangeId=-1&lastChangeId64=-1)。当我单击它时,URL 会在浏览器中打开。当我输入我的凭据时,我收到一个 JSON 响应,当脚本尝试访问该 URL 时我没有收到该响应。根据 fiddler 的说法,脚本的请求会返回一个错误页面。该脚本从不询问我的凭据,这与我尝试通过浏览器访问提琴手中的 URL 不同。

我确实检查了托管我的 TFS URL 的 IIS 网站的身份验证配置。它启用了匿名访问,启用了以 NTLM 作为提供者的 Windows 身份验证,并且禁用了其他方法。我确实尝试将 Negotiate 添加为 Windows 身份验证提供程序,但这并没有解决问题。

关于如何解决这个问题,我很茫然。任何指针、参考、潜在的解决方案等将不胜感激。谢谢。

下面是 TFS 提供的用于配置代理的批处理文件的代码:

@echo off

rem ********************************************************************************
rem Unblock specific files.
rem ********************************************************************************
setlocal
if defined VERBOSE_ARG (
  set VERBOSE_ARG='Continue'
) else (
  set VERBOSE_ARG='SilentlyContinue'
)

rem Unblock the following types of files:
rem 1) The files in the root of the layout folder. E.g. .cmd files.
rem
rem 2) The PowerShell scripts delivered with the agent. E.g. capability scan scripts under "bin\"
rem and legacy handler scripts under "externals\vstshost\".
rem
rem 3) The DLLs potentially loaded from a PowerShell script (e.g. DLLs in Agent.ServerOMDirectory).
rem Otherwise, Add-Type may result in the following error:
rem   Add-Type : Could not load file or assembly 'file:///[...].dll' or one of its dependencies.
rem   Operation is not supported.
rem Reproduced on Windows 8 in PowerShell 4. Changing the execution policy did not appear to make
rem a difference. The error reproduced even with the execution policy set to Bypass. It may be a
rem a policy setting.
powershell.exe -NoLogo -Sta -NoProfile -NonInteractive -ExecutionPolicy Unrestricted -Command "$VerbosePreference = %VERBOSE_ARG% ; Get-ChildItem -LiteralPath '%~dp0' | ForEach-Object { Write-Verbose ('Unblock: {0}' -f $_.FullName) ; $_ } | Unblock-File | Out-Null ; Get-ChildItem -Recurse -LiteralPath '%~dp0bin', '%~dp0externals' | Where-Object { $_ -match '\.(ps1|psd1|psm1)$' } | ForEach-Object { Write-Verbose ('Unblock: {0}' -f $_.FullName) ; $_ } | Unblock-File | Out-Null ; Get-ChildItem -LiteralPath '%~dp0externals\vstsom', '%~dp0externals\vstshost' | Where-Object { $_ -match '\.(dll|exe)$' } | ForEach-Object { Write-Verbose ('Unblock: {0}' -f $_.FullName) ; $_ } | Unblock-File | Out-Null"

if "%~1" equ "remove" (
    rem ********************************************************************************
    rem Unconfigure the agent.
    rem ********************************************************************************
    "%~dp0bin\Agent.Listener.exe" %*
) else (
    rem ********************************************************************************
    rem Configure the agent.
    rem ********************************************************************************
    "%~dp0bin\Agent.Listener.exe" configure %*
)

代理的控制台输出:

>> Connect:

Enter server URL > http://{mydomain}/
Enter authentication type (press enter for Integrated) >
Connecting to server ...
TF400813: Resource not available for anonymous access. Client authentication required.
Failed to connect.  Try again or ctrl-c to quit
Enter server URL > http://{mydomain}/
Enter authentication type (press enter for Integrated) > Negotiate
Enter user name > {myUserName}
Enter password > {myPassword}
Connecting to server ...
TF400813: Resource not available for anonymous access. Client authentication required.
Failed to connect.  Try again or ctrl-c to quit
Enter server URL >

来自日志文件的堆栈跟踪:

[2020-04-13 16:18:39Z ERR  Terminal] Microsoft.VisualStudio.Services.Common.VssUnauthorizedException: TF400813: Resource not available for anonymous access. Client authentication required.
   at Microsoft.VisualStudio.Services.Common.VssHttpMessageHandler.<SendAsync>d__17.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
   at Microsoft.VisualStudio.Services.Common.VssHttpRetryMessageHandler.<SendAsync>d__3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Net.Http.HttpClient.<FinishSendAsync>d__58.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
   at Microsoft.VisualStudio.Services.WebApi.VssHttpClientBase.<SendAsync>d__45.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
   at Microsoft.VisualStudio.Services.WebApi.VssHttpClientBase.<SendAsync>d__42`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
   at Microsoft.VisualStudio.Services.Location.Client.LocationHttpClient.<GetConnectionDataAsync>d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
   at Microsoft.VisualStudio.Services.WebApi.Location.VssServerDataProvider.<ConnectAsync>d__41.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.VisualStudio.Services.Agent.AgentServer.<ConnectAsync>d__3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.VisualStudio.Services.Agent.Listener.Configuration.BuildReleasesAgentConfigProvider.<TestConnectionAsync>d__14.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.VisualStudio.Services.Agent.Listener.Configuration.ConfigurationManager.<ConfigureAsync>d__7.MoveNext()

标签: tfs

解决方案


我尝试在本地 TFS 中部署代理,发现默认身份验证类型为Integrated,请尝试negotiate改用:

在此处输入图像描述


推荐阅读