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

时间:2009-03-12 01:41:19

标签: c# asp.net security iis directoryservices

当我尝试从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框架版本。请参阅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
域名:(MyDomain)
登录类型:3
登录过程:NtLmSsp
认证包:NTLM
工作站名称:(MyWorkstationId)
来电者用户名: -
来电域名: -
来电登录ID: -
来电进程ID: -
过境服务: -
来源网络地址:10.12.13.35
来源港口:1708年

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

8 个答案:

答案 0 :(得分:2)

如果是身份问题,您可以尝试将IIS 5.1应用程序设置为使用Integrated Windows Authentication,然后在您的IIS5.1网站上的system.web下将以下内容添加到web.config以启用{ {3}}

<identity impersonate="true"/>
<authentication mode="Windows" />

答案 1 :(得分:1)

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

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

See MSDN for more info.

答案 2 :(得分:1)

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

我过去使用的所有解决方案都要求您对应用池进行硬编码以使用具有权限的帐户,设置烦恼。帐户到具有其他计算机权限的域帐户,或使用在域帐户下的IIS 5.1计算机上运行的Windows服务连接到其他服务器。

如果您使用的是Kerberos,则不适用,但AD默认使用NTLM。

答案 3 :(得分:0)

你到底想要读什么?它是否与您的应用程序处于相同的路径中?

答案 4 :(得分:0)

我现在有点难过,为什么你不能让这个工作。你可以尝试一下临时工作。实例化DirectoryEntry对象时,可以使用以下构造函数重载之一:

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

记录于:MSDN: DirectoryEntry Constructor (String, String, String)

...或...

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

记录于:MSDN: DirectoryEntry Constructor (String, String, String, 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;
  }
}

您可以使用上面的其中一个替换构造函数。不可否认,这是在黑暗中刺伤:)。

答案 5 :(得分:0)

当我遇到这个问题时,我发现只是在Windows文件共享上验证我的自我就解决了这个问题。根据经验,我认为WMI / ADSI / COM对未经过身份验证的用户没有很好的支持。我相信当您未与Windows域关联时会出现此问题。

答案 6 :(得分:0)

如果它确实是NTLM双网店问题,您可以使用SETSPN实用程序为目标IIS服务器创建服务主体命名实例。

然后,您可以进入Active Directory,然后允许计算机对象(基本上是NETWORK SERVICE或LOCAL SERVICE主体)将其凭据委派给正确注册的SPN。

然后你可以跳到各地!但是,请注意!当你启用双跳时,人们会因尖锐的东西而伤害自己!

好的知识库文章:

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

答案 7 :(得分:0)

我相信DirectoryEntry.Exists会默默地忽略所提供的任何凭据,并使用经过身份验证的用户的信用卡。这似乎与您描述的行为相符。对于AD工作,我们从不使用它。