尝试连接到远程IIS服务器时出现“拒绝访问” – C#
当我尝试从IIS 5.1下运行的C#应用程序连接到远程IIS 6服务器时,我收到“Access Deined”COMException。
有任何想法吗? 我遇到了原始问题的所有相同问题。
更新 – 4/1/09
我找到了这个解决方案( http://www.codeproject.com/KB/cs/Start_Stop_IIS_Website.aspx ),它包含一个连接到IIS服务器以启动和停止网站的窗口应用程序。 我能够在我的工作站上运行它并连接到IIS服务器。
呃….为什么我可以运行这个独立应用程序而不是我的ASP.NET应用程序?
原版的
当我尝试使用DirectoryEntry.Exist方法从远程计算机连接到IIS以检查IIS服务器是否有效时,我收到“拒绝访问”COMException。
string path = string.Format("IIS://{0}/W3SVC", server); if(DirectoryEntry.Exist(path)) { //do something is valid.... }
我是一个活动目录组的成员,该组已添加到管理员组到我尝试连接的IIS服务器。
有没有人遇到这个问题,知道如何解决它?
更新:
@Kev – 这是一个ASP.NET应用程序。 此外,我可以通过IIS6管理器在没有用户名和密码的情况下连接到远程服务器。
@Chris – 我正在尝试连接到远程服务器以显示虚拟directorys的数量,并确定每个目录的.NET框架版本。 看到这个问题。
@dautzenb – 我的ASP.NET应用程序在IIS 5.1下运行,试图连接到IIS 6服务器。 我可以在远程服务器上的本地ASPNET帐户的安全日志中看到故障审核。 当我尝试调试应用程序时,我在我的域帐户下运行,但仍然拒绝访问。
更新2:
@Kev – 我能够建立使用以下重载创建DirectoryEntry对象:
public DirectoryEntry ( string path, string username, string password )
但是,当我调试应用程序时,所有属性都包含“抛出类型’System.Runtime.InteropServices.COMException’的exception”。
此外,AuthenticationType属性设置为Secure。
更新3:
每次我尝试建立连接时,以下两个失败审核条目都在远程IIS服务器的安全事件日志中:
第一件事:
事件类别:帐户登录
事件ID:680
记录尝试:MICROSOFT_AUTHENTICATION_PACKAGE_V1_0
登录帐号:ASPNET
源工作站:
错误代码:0xC0000234
第二件事:
事件类别:登录/注销
事件ID:529
登录失败:
原因:未知用户名或密码错误
用户名:ASPNET
域名:(MyDomain)
登录类型:3
登录过程:NtLmSsp
身份validation包:NTLM
工作站名称:(MyWorkstationId)
来电者用户名: –
来电域: –
来电登录ID: –
来电进程ID: –
过境服务: –
来源网络地址:10.12.13.35
来源港口:1708
模拟设置为true,用户名和密码为空。 它使用远程IIS服务器上的ASPNET帐户。
如果是身份问题,您可以尝试将IIS 5.1应用程序设置为使用集成Windows身份validation ,然后在system.web下的IIS5.1网站上将以下内容添加到web.config以启用模拟 。
由于这是一个ASP.NET应用程序,因此它在IIS的应用程序池中运行。 此应用程序池使用特定用户(“本地系统”,“网络服务”或其他用户)运行。
此用户是否有足够的权限连接到远程服务器?
有关详细信息,请参阅MSDN。
这看起来可能是一个双跳问题。 如果您使用NTLM模拟网站的当前用户,则该模拟仅在该服务器上有效(在这种情况下为您的IIS 5.1服务器)。 如果您尝试使用该网站连接到另一台服务器,您实际上会遇到问题,因为它无法将令牌传递给在模拟期间使用的另一台服务器。 如果您通过机器调试站点,转到另一个盒子,情况也是如此。 您的本地计算机正在validation您,但它无法模拟您到另一台服务器。
我过去使用的所有解决方案都要求您对应用程序池进行硬编码以使用具有权限的帐户,设置烦恼。 帐户到具有其他计算机权限的域帐户,或使用在域帐户下的IIS 5.1计算机上运行的Windows服务连接到其他服务器。
如果您使用的是Kerberos,则不适用,但AD默认使用NTLM。
你究竟在哪里读书? 它是否与您的应用程序处于相同的路径中?
当我遇到这个问题时,我发现只是在Windows文件共享上validation我的自我就解决了这个问题。 根据经验,我认为WMI / ADSI / COM对未经过身份validation的用户没有很好的支持。 我相信当您未与Windows域关联时会出现此问题。
如果它确实是NTLM双跳问题,您可以使用SETSPN实用程序为目标IIS服务器创建服务主体命名实例。
然后,您可以进入Active Directory,然后允许计算机对象(基本上是NETWORK SERVICE或LOCAL SERVICE主体)将其凭据委派给正确注册的SPN。
那你就可以到处跳跃! 但是,请注意! 当你启用双跳时,人们会因尖锐的东西而伤害自己!
好的知识库文章:
我相信DirectoryEntry.Exists会默默地忽略所提供的任何凭据,并使用经过身份validation的用户的信用。 这似乎与您描述的行为相符。 对于AD工作,我们从不使用它。
我有点难过,为什么你不能让这个工作。 你可以尝试一下临时工作。 实例化DirectoryEntry
对象时,您可以使用以下构造函数重载之一:
public DirectoryEntry( string path, string username, string password )
记录于: MSDN:DirectoryEntry构造函数(字符串,字符串,字符串)
…要么…
public DirectoryEntry( string path, string username, string password, AuthenticationTypes authenticationType )
记录于: MSDN:DirectoryEntry构造函数(字符串,字符串,字符串,AuthenticationTypes)
碰巧我正在我的虚拟服务器盒上构建测试AD环境,以便新项目执行类似的操作。 当我开始运行时,我将有一个游戏,看看我是否可以重现你遇到的问题。 在此期间,让我们知道如果您尝试上面引用的这些构造函数重载会发生什么。
更新(回答Michaels评论):
由于刚刚逃避我的原因,我们无法在特定场景中使用DirectoryEntry.Exists()
,这段代码会在我们的某个应用中立即被调用:
public static bool MetabasePathExists(string metabasePath) { try { using(DirectoryEntry site = new DirectoryEntry(metabasePath)) { if(site.Name != String.Empty) { return true; } return false; } } catch(COMException ex) { if(ex.Message.StartsWith("The system cannot find the path specified")) { return false; } LogError(ex, String.Format("metabasePath={0}", metabasePath)); throw; } catch(Exception ex) { LogError(ex, String.Format("metabasePath={0}", metabasePath)); throw; } }
您可以使用上面的一个替换构造函数。 不可否认,它是在黑暗中刺伤:)。