IIS7 模拟无法访问 TFS 存储库

Posted

技术标签:

【中文标题】IIS7 模拟无法访问 TFS 存储库【英文标题】:IIS7 Impersonation doesn't work to access TFS repository 【发布时间】:2012-03-30 12:58:50 【问题描述】:

我正在尝试构建一个在 TFS 中添加工作项的 ASP.NET 页面。

我已启用模拟和 Windows 身份验证:

<authentication mode="Windows" />
<identity impersonate="true" password="" userName="" />
<customErrors mode="Off" /> 

在页面中,我访问 TFS 并尝试添加一个工作项:

TfsTeamProjectCollection prjCollection = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri("xxx"));
WorkItemStore store = prjCollection.GetService<WorkItemStore>();
...

但是,它仅在我在 ASP.NET Impersonation 中选择 SpecificUser 并存储凭据时才有效。选择Authenticated user时不起作用。

我检查了 SpecificUser 是否与 Authenticated 相同,但在后一种情况下出现权限错误(这表明模拟无法正常工作)。

TF30063: You are not authorized to access XXX. ---> System.Net.WebException: The remote server returned an error: (401) Unauthorized.
   at System.Net.HttpWebRequest.GetResponse()
   at     Microsoft.TeamFoundation.Client.TeamFoundationClientProxyBase.AsyncWebRequest.ExecRequest(Object obj)
   --- End of inner exception stack trace ---
   at     Microsoft.TeamFoundation.Client.TeamFoundationClientProxyBase.ProcessHttpResponse(HttpWebResponse response, Stream responseStream, WebException webException, XmlReader& xmlResponseReader)
   at Microsoft.TeamFoundation.Client.TeamFoundationClientProxyBase.ExecWebServiceRequest(HttpWebRequest request, XmlWriter requestXml, String methodName, HttpWebResponse& response)
   at Microsoft.TeamFoundation.Framework.Client.LocationWebService.Connect(Int32 connectOptions, ServiceTypeFilter[] serviceTypeFilters, Int32 lastChangeId)
   at Microsoft.TeamFoundation.Framework.Client.FrameworkServerDataProvider.Connect(ConnectOptions connectOptions)
   at Microsoft.TeamFoundation.Framework.Client.FrameworkServerDataProvider.EnsureConnected(ConnectOptions optionsNeeded)
   at Microsoft.TeamFoundation.Framework.Client.FrameworkServerDataProvider.get_InstanceId()
   at Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItemStore.InitializeInternal()
   at Microsoft.TeamFoundation.Client.TfsTeamProjectCollection.InitializeTeamFoundationObject(String fullName, Object instance)
   at Microsoft.TeamFoundation.Client.TfsConnection.CreateServiceInstance(Assembly assembly, String fullName)
   at Microsoft.TeamFoundation.Client.TfsConnection.GetService(Type serviceType)
   at Microsoft.TeamFoundation.Client.TfsConnection.GetService[T]()
   at ASP.index_aspx.__Render__control1(htmlTextWriter __w, Control parameterContainer)

以下变量在两种情况下看起来相同:

HttpContext.Current.Request.LogonUserIdentity.Name
HttpContext.Current.Request.IsAuthenticated
HttpContext.Current.User.Identity.Name
System.Environment.UserName
System.Security.Principal.WindowsIdentity.GetCurrent().Name

有什么想法吗?

编辑:

确实,正如 John 下面提到的,问题是由 Kerberos 委派引起的。

我发现以下文章和随附的工具在解释和缓解此问题方面非常有用:

DelegConfig - A Tool To help resolve Kerberos authentication and delegation issues

【问题讨论】:

【参考方案1】:

我想你可能有"double hop" 的问题。

【讨论】:

+1 ... 刚刚将一组基于 Web 的 ui 工具(与 tfs 接口)部署到“另一台机器”上,作为 iis 上的 Web 应用程序。我观察到与这篇文章中描述的行为相同的行为。任何已知的解决方法?提前致谢。 是的。点击我回答中的“双跳”链接。【参考方案2】:

基于this的文章,值得一试添加EnsureAuthenticated();

TfsTeamProjectCollection prjCollection = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri("xxx"));
prjCollection.EnsureAuthenticated();
WorkItemStore store = prjCollection.GetService<WorkItemStore>();

我从未尝试过这个,所以我只能希望它会起作用。

【讨论】:

【参考方案3】:

运行 IIS 应用程序的应用程序池是谁?默认情况下,我认为它是 IIUSR 帐户之一,不一定是具有 TFS 服务器凭据的域帐户。

【讨论】:

它使用默认的 ApplicationPoolIdentity,但这就是我设置模拟的原因,以便可以使用用户的凭据访问 TFS。

以上是关于IIS7 模拟无法访问 TFS 存储库的主要内容,如果未能解决你的问题,请参考以下文章

TFS--解决新创建的windows用户无法访问TFS的问题

TFS,无法签入解决方案,accordionlist.gif:进程无法访问该文件,因为它正被另一个进程使用

无法使用 OSX Server 3.2.1 在 XCode 6.0.1 中创建 CI Bot

XCode 5 - 无法访问本地 git 存储库

AWS CodePipeline 无法访问组织的存储库

使用异步存储库模式 - 无法访问已处置的对象