尝试连接到远程 IIS 服务器时出现“拒绝访问” - C#
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/637090/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
"Access Denied" when trying to connect to remote IIS server - C#
提问by Michael Kniskern
I receive an "Access Deined" COMException when I try to connect to a remote IIS 6 server from my C# application that is running under IIS 5.1.
当我尝试从在 IIS 5.1 下运行的 C# 应用程序连接到远程 IIS 6 服务器时,我收到“访问定义”COMException。
Any ideas? I am experiencing all the same issues with the original questions.
有任何想法吗?我遇到了与原始问题相同的问题。
Update - 4/1/09
更新 - 4/1/09
I found this solution (http://www.codeproject.com/KB/cs/Start_Stop_IIS_Website.aspx) that consists of a window application connecting to an IIS server to start and stop web sites. I am able to run it on my workstation and connect to the IIS server.
我找到了这个解决方案(http://www.codeproject.com/KB/cs/Start_Stop_IIS_Website.aspx),它由一个连接到 IIS 服务器以启动和停止网站的窗口应用程序组成。我能够在我的工作站上运行它并连接到 IIS 服务器。
Ugh....why can I run this stand alone application but not my ASP.NET application?
呃....为什么我可以运行这个独立的应用程序而不是我的 ASP.NET 应用程序?
Original
原来的
I receive an "Access Denied" COMException when I try to connect to IIS from a remote machine using the DirectoryEntry.Exist method to check to see if the IIS server is valid.
当我尝试使用 DirectoryEntry.Exist 方法从远程计算机连接到 IIS 以检查 IIS 服务器是否有效时,我收到“拒绝访问”COMException。
string path = string.Format("IIS://{0}/W3SVC", server);
if(DirectoryEntry.Exist(path))
{
//do something is valid....
}
I am a member of an active directory group that has been added to the Administrators groups to the IIS server I am trying to connect to.
我是 Active Directory 组的成员,该组已添加到我尝试连接的 IIS 服务器的管理员组。
Has anyone experience this issue and know how to resolve it?
有没有人遇到过这个问题并知道如何解决它?
UPDATE:
更新:
@Kev - It is an ASP.NET application. Also, I can connect without an username and password to the remote server through IIS6 Manager.
@Kev - 它是一个 ASP.NET 应用程序。此外,我可以在没有用户名和密码的情况下通过 IIS6 管理器连接到远程服务器。
@Chris - I am trying to connect to the remote server to display the number of virtual directorys and determine the .NET framework version of each directory. See thisSO question.
@Chris - 我正在尝试连接到远程服务器以显示虚拟目录的数量并确定每个目录的 .NET 框架版本。看到这个问题。
@dautzenb - My ASP.NET application is running under IIS 5.1 trying to connect to an IIS 6 server. I can see fault audits in the security log for my local ASPNET account on the remote server. When I try to debug the application, I am running under my domain account and still get the Access is denied.
@dautzenb - 我的 ASP.NET 应用程序在 IIS 5.1 下运行,试图连接到 IIS 6 服务器。我可以在远程服务器上的本地 ASPNET 帐户的安全日志中看到错误审核。当我尝试调试应用程序时,我在我的域帐户下运行,但仍然拒绝访问。
UPDATE 2:
更新 2:
@Kev - I was able to establish to create a DirectoryEntry object using the following overload:
@Kev - 我能够使用以下重载来建立创建 DirectoryEntry 对象:
public DirectoryEntry
(
string path,
string username,
string password
)
But, all of the properties contain a " threw an exception of type 'System.Runtime.InteropServices.COMException'" while I debug the app.
但是,在我调试应用程序时,所有属性都包含“抛出类型为‘System.Runtime.InteropServices.COMException’的异常”。
Also, the AuthenticationType property is set to Secure.
此外,AuthenticationType 属性设置为 Secure。
UPDATE 3:
更新 3:
The following two failure audit entries were in the remote IIS server's security event log every time I tried to establish a connection:
每次尝试建立连接时,远程 IIS 服务器的安全事件日志中都会出现以下两个失败审核条目:
First event:
第一次活动:
Event Category: Account Logon
Event ID: 680
Log attempt by: MICROSOFT_AUTHENTICATION_PACKAGE_V1_0
Logon account: ASPNET
Source Workstation:
Error Code: 0xC0000234
事件类别:帐户登录
事件 ID:680
尝试
登录:MICROSOFT_AUTHENTICATION_PACKAGE_V1_0登录帐户:ASPNET
源工作站:
错误代码:0xC0000234
Second event:
第二场活动:
Event Category: Logon/Logoff
Event ID: 529
Logon Failure:
Reason: Unknown user name or bad password
User Name: ASPNET
Domain: (MyDomain)
Logon Type: 3
Logon Process: NtLmSsp
Authentication Package: NTLM
Workstation Name: (MyWorkstationId)
Caller User Name: -
Caller Domain: -
Caller Logon ID: -
Caller Process ID: -
Transited Services: -
Source Network Address: 10.12.13.35
Source Port: 1708
事件类别:登录/注销
事件 ID:529
登录失败:
原因:未知用户名或密码错误
用户名:ASPNET
域:(MyDomain)
登录类型:3
登录进程:NtLmSsp
身份验证包:NTLM
工作站名称:(MyWorkstationId)
呼叫者用户名称: -
呼叫方域: -
呼叫方登录 ID: -
呼叫方进程 ID: -
传输的服务: -
源网络地址: 10.12.13.35
源端口: 1708
Impersonation is set to true and the username and password are blank. It is using the ASPNET account on the remote IIS server.
Impersonation 设置为 true,用户名和密码为空。它使用远程 IIS 服务器上的 ASPNET 帐户。
回答by Chris
Where exactly are you trying to read too? Is it in under the same path as your application?
你到底想在哪里阅读?它与您的应用程序在同一路径下吗?
回答by Dre
Since this is an ASP.NET application, it runs in an Application Pool of IIS. This Application Pool runs using a specific user("Local System", "Network Service" or another user).
由于这是一个 ASP.NET 应用程序,它在 IIS 的应用程序池中运行。此应用程序池使用特定用户(“本地系统”、“网络服务”或其他用户)运行。
Does this user have enough rights to connect to a remote server ?
此用户是否有足够的权限连接到远程服务器?
回答by Kev
I'm sort of stumped at the moment as to why you can't get this working. There is a temporary work around you could try. When instantiating the DirectoryEntry
object you could use one of the following constructor overloads:
我现在有点不明白为什么你不能让它工作。你可以尝试一个临时的工作。实例化DirectoryEntry
对象时,您可以使用以下构造函数重载之一:
public DirectoryEntry(
string path,
string username,
string password
)
Documented at: MSDN: DirectoryEntry Constructor (String, String, String)
记录在:MSDN: DirectoryEntry Constructor (String, String, String)
...or...
...或者...
public DirectoryEntry(
string path,
string username,
string password,
AuthenticationTypes authenticationType
)
Documented at: MSDN: DirectoryEntry Constructor (String, String, String, AuthenticationTypes)
记录在:MSDN: DirectoryEntry Constructor (String, String, String, AuthenticationTypes)
As it happens I'm building a test AD environment on my virtual server box for a new project to do similar stuff. When I get it up and running I'll have a play around to see if I can reproduce the problem you're encountering. In the meantime let us know what happens if you try these constructor overloads referenced above.
碰巧的是,我正在我的虚拟服务器上构建一个测试 AD 环境,用于一个新项目来做类似的事情。当我启动并运行它时,我会尝试一下,看看我是否可以重现您遇到的问题。同时,让我们知道如果您尝试上面引用的这些构造函数重载会发生什么。
Update (In answer to Michaels comment):
更新(回应迈克尔斯的评论):
For reasons that evade me just now, we couldn't use DirectoryEntry.Exists()
in a particular scenario, there is this snippet of code that gets called now and again in one of our apps:
出于刚才回避我的原因,我们无法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;
}
}
You could replace the constructor with one of the ones from above. Admittedly it's a stab in the dark :).
您可以用上面的构造函数之一替换构造函数。不可否认,这是在黑暗中刺伤:)。
回答by Nick Bolton
When I had this problem, I found that simply authenticating my self on a Windows file share solved the problem. From experience, I think that WMI/ADSI/COM doesn't have great support for not-already-authenticated users. I believe this issue occurs when you're not associated with a Windows domain.
当我遇到这个问题时,我发现只需在 Windows 文件共享上验证我自己就可以解决这个问题。根据经验,我认为 WMI/ADSI/COM 对未通过身份验证的用户没有很好的支持。我相信当您未与 Windows 域关联时会出现此问题。
回答by holz
If it is an identity problem, you could try setting your IIS 5.1 application to use Integrated Windows Authentication, and then add the following to you web.config on your IIS5.1 web site under system.web to enable impersonation.
如果是身份问题,您可以尝试将 IIS 5.1 应用程序设置为使用集成 Windows 身份验证,然后将以下内容添加到您的 IIS5.1 网站上的 web.config system.web 下以启用模拟。
<identity impersonate="true"/>
<authentication mode="Windows" />
回答by holz
This looks like it may be a double-hop issue. If you are impersonating the current user of a website using NTLM, that impersonation is only valid on that server (your IIS 5.1 server in this case). If you try to connect to another server using the web site, you are actually going to have issues as it cannot pass the token to another server that was used during impersonation. The same is true if you are debugging your site through your machine, going to another box. Your local machine is authenticating you, but it cannot impersonate you to another server.
这看起来可能是一个双跳问题。如果您使用 NTLM 模拟网站的当前用户,则该模拟仅在该服务器(在本例中为您的 IIS 5.1 服务器)上有效。如果您尝试使用该网站连接到另一台服务器,您实际上会遇到问题,因为它无法将令牌传递到模拟期间使用的另一台服务器。如果您正在通过您的机器调试您的站点,转到另一个盒子,情况也是如此。您的本地机器正在对您进行身份验证,但它无法冒充您到另一台服务器。
All of the solutions I have used in the past require you to hard code the app pool to use an account that has permissions, set the annony. account to a domain account with permissions on the other machine, or use a windows service running on the IIS 5.1 machine, under a domain account, to connect to the other server.
我过去使用的所有解决方案都要求您对应用程序池进行硬编码以使用具有权限的帐户,将 anony. 帐户到在另一台机器上具有权限的域帐户,或使用在 IIS 5.1 机器上运行的 Windows 服务,在域帐户下连接到另一台服务器。
If you are using Kerberos, this wouldn't apply, but AD uses NTLM by default.
如果您使用的是 Kerberos,这将不适用,但 AD 默认使用 NTLM。
回答by holz
If it is indeed a NTLM doublehop issue you could use the SETSPN utility to create service principal named instances for your target IIS servers.
如果确实是 NTLM 双跳问题,您可以使用 SETSPN 实用程序为目标 IIS 服务器创建服务主体命名实例。
Then you could go into Active Directory, and then allow the computer object (basically the NETWORK SERVICE or LOCAL SERVICE principals) to delegate its credentials to a correctly registered SPN.
然后,您可以进入 Active Directory,然后允许计算机对象(基本上是 NETWORK SERVICE 或 LOCAL SERVICE 主体)将其凭据委派给正确注册的 SPN。
Then you could hop-hop-hop all over the place! But, be warned! People can hurt themselves on sharp pointy things when you enable double-hop!
然后你可以到处跳!但是,请注意!当您启用双跳时,人们可能会被尖锐的东西伤害到自己!
Good KB articles to read:
值得阅读的好知识库文章:
回答by serialhobbyist
I believe that DirectoryEntry.Exists silently ignores any credentials supplied and uses the creds of the authenticated user. This seems to match the behaviour you've described. For AD work, we never use it for this reason.
我相信 DirectoryEntry.Exists 会默默地忽略提供的任何凭据并使用经过身份验证的用户的凭据。这似乎与您描述的行为相符。对于 AD 工作,我们从不使用它。