尝试连接远程IIS服务器时出现“访问被拒绝”- C#

3
当我试图从运行在IIS 5.1下的C#应用程序连接到远程IIS 6服务器时,我收到了“访问被拒绝”的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 Manager连接到远程服务器而不需要用户名和密码。

@Chris - 我正在尝试连接到远程服务器以显示虚拟目录的数量,并确定每个目录的.NET框架版本。请参见this SO问题。

@dautzenb - 我的ASP.NET应用程序正在IIS 5.1下运行,尝试连接到IIS 6服务器。我可以在远程服务器上看到我的本地ASPNET帐户的故障审核。当我尝试调试应用程序时,我正在使用我的域帐户运行,但仍然收到“访问被拒绝”的消息。

更新2:

@Kev - 我能够使用以下重载创建DirectoryEntry对象:

public DirectoryEntry
(    
    string path,    
    string username,    
    string password
)

然而,在调试应用程序时,所有属性都包含一个“抛出了类型为'System.Runtime.InteropServices.COMException'的异常”。

此外,AuthenticationType属性设置为Secure。

更新3:

每次尝试建立连接时,远程IIS服务器的安全事件日志中都会出现以下两个失败审核条目:

第一个事件:

事件类别:帐户登录
事件ID:680
登录尝试者:MICROSOFT_AUTHENTICATION_PACKAGE_V1_0
登录帐户:ASPNET
来源工作站:
错误代码:0xC0000234

第二个事件:

事件类别:登录/注销
事件 ID:529
登录失败:
原因:未知的用户名或密码错误
用户名:ASPNET
域名:(我的域名)
登录类型:3
登录过程:NtLmSsp
身份验证包:NTLM
工作站名称:(我的工作站ID)
调用者用户名:-
调用者域:-
调用者登录 ID:-
调用者进程 ID:-
传输服务:-
源网络地址:10.12.13.35
源端口:1708

模拟设置为 true,用户名和密码为空。它在远程 IIS 服务器上使用 ASPNET 帐户。


这是控制台/Windows应用程序还是ASP.NET? - Kev
还有,当您使用PC上的IIS MMC通过右键单击上下文菜单中的“连接...”连接到远程服务器时会发生什么?您能否在不使用用户名和密码(作为连接)的情况下进行连接? - Kev
@Kev - 我已经更新了我的问题,以便向您提出问题。 - Michael Kniskern
你知道在调试时是否使用了你的域帐户吗?你是使用Visual Studio Web服务器进行调试还是使用IIS?如果你使用调试器连接到IIS,那么你仍然是作为IIS用户运行,这很可能是NETWORK SERVICE或MACHINE\IUSR_MACHINE或MACHINE\ASPNET。 - Mike Marshall
@Kev - 这是我的用户名和域名。 - Michael Kniskern
显示剩余2条评论
8个回答

2
如果是身份验证问题,您可以尝试将您的IIS 5.1应用设置为使用集成Windows身份验证,然后在您的IIS 5.1网站的web.config文件中添加以下内容以启用模拟
<identity impersonate="true"/>
<authentication mode="Windows" />

我已经尝试过这个,但它没有起作用。我甚至尝试了明确使用我的凭据,但仍然没有起作用。 - Michael Kniskern

1

由于这是一个ASP.NET应用程序,它在IIS的应用程序池中运行。该应用程序池使用特定的用户(“本地系统”,“网络服务”或其他用户)运行。

这个用户是否有足够的权限连接到远程服务器?

请参阅MSDN获取更多信息。


1

这看起来可能是一个双跳问题。如果您正在使用NTLM模拟网站的当前用户,则该模拟仅在该服务器上有效(在本例中为您的IIS 5.1服务器)。如果您尝试使用网站连接到另一台服务器,实际上会出现问题,因为它无法将在模拟期间使用的令牌传递给另一台服务器。如果您通过计算机调试站点并转到另一台计算机,则情况也是如此。您的本地计算机正在对您进行身份验证,但它无法模拟您对另一台服务器。

我过去使用的所有解决方案都要求您硬编码应用程序池以使用具有权限的帐户,将annony.帐户设置为具有其他机器上权限的域帐户,或者在运行在域帐户下的IIS 5.1机器上使用Windows服务连接到其他服务器。

如果您正在使用Kerberos,则不适用此方法,但AD默认使用NTLM。


0

目前我有些困惑,不知道为什么你无法让它正常工作。你可以尝试一个临时解决方法。在实例化DirectoryEntry对象时,你可以使用以下构造函数重载之一:

public DirectoryEntry(
    string path,
    string username,
    string password
)

文档记录在:MSDN:DirectoryEntry构造函数(String,String,String)

...或...

public DirectoryEntry(
    string path,
    string username,
    string password,
    AuthenticationTypes authenticationType
)

文档位于:MSDN:DirectoryEntry构造函数(String,String,String,AuthenticationTypes)

恰好我正在我的虚拟服务器上构建一个测试AD环境,为了做类似的事情。当我把它运行起来后,我会试着玩一下,看看能否重现你遇到的问题。与此同时,请告诉我们如果你尝试使用上面提到的这些构造函数重载会发生什么。

更新(回答Michael的评论):

由于某种原因,我们在特定场景下无法使用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;
  }
}

你可以使用上面的构造函数之一来替换构造函数。不过这可能有点冒险 :)


在调用DirectoryEntry.Exists方法之前,我还没有创建DirectoryEntry对象。我是否应该在进行检查之前登录到远程iis服务器? - Michael Kniskern
@Kev - 当我检查DirectoryEntry对象的Name属性时,我会收到“访问被拒绝”的COMExcption异常。 - Michael Kniskern

0

我相信DirectoryEntry.Exists会默默地忽略提供的任何凭据并使用已认证用户的凭据。这似乎符合您所描述的行为。出于这个原因,对于AD工作,我们从不使用它。


0
当我遇到这个问题时,我发现只需在Windows文件共享上进行身份验证即可解决问题。从经验来看,我认为WMI / ADSI / COM对于未经身份验证的用户支持不够好。我相信当您没有与Windows域相关联时会出现此问题。

0
你具体是在哪里尝试读取呢?是在应用程序相同的路径下吗?

0
如果确实是NTLM双跳问题,您可以使用SETSPN实用程序为目标IIS服务器创建服务主体命名实例。
然后,您可以进入Active Directory,允许计算机对象(基本上是NETWORK SERVICE或LOCAL SERVICE主体)将其凭据委派给正确注册的SPN。
然后您可以随心所欲地进行多次跳转!但请注意!当启用双跳时,人们可能会在尖锐的物品上受伤!
阅读的好文献:

http://support.microsoft.com/kb/929650


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接