启动IIS时,为啥提示拒绝访问?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了启动IIS时,为啥提示拒绝访问?相关的知识,希望对你有一定的参考价值。

就是运行 “Internet 信息服务器[IIS]”时,出现这个,是什么情况啊?请高手回答,我从来没有设过什么密码、就连开机的密码也没设置过,为什么这个要密码。?以前用的好好的,现在不行了,重装一样还不行。懂的发言。谢谢!

建议用一下步骤重新安装。 a) 把整个IIS卸载 b) 把%windir%\\system32\\inetsrv 删除掉 把%windir%\\iisX.log删除掉。X 是(w2k-iis5.log,xp-iis6.log) 也把\\inetpub\\目录删除掉 (可以在safe-mode里删除) c) 重装IIS,打上最新补丁 参考技术A 可能是你的使用期限到了··

从 IIS 应用程序打开命名管道通道时,WCF 访问被拒绝

【中文标题】从 IIS 应用程序打开命名管道通道时,WCF 访问被拒绝【英文标题】:WCF Access is Denied when opening named pipe channel from IIS application 【发布时间】:2018-05-06 20:12:58 【问题描述】:

我们有一些旧的 Web 应用程序代码正在更新并移植到 .NET 4.0 运行时。

代码位于类库中,并使用 WCF 连接到命名管道端点。

当我从控制台应用程序启动连接时,一切正常。

当我从 Web 应用程序启动连接时,我收到一个异常:

Access is denied
Server stack trace:
  at System.ServiceModel.Channels.AppContainerInfo.GetCurrentProcessToken()
  at System.ServiceModel.Channels.AppContainerInfo.RunningInAppContainer()
  at System.ServiceModel.Channels.AppContainerInfo.get_IsRunningInAppContainer()
  at System.ServiceModel.Channels.PipeSharedMemory.BuildPipeName(String pipeGuid)
  at System.ServiceModel.Channels.PipeSharedMemory.get_PipeName()
  at System.ServiceModel.Channels.PipeConnectionInitiator.GetPipeName(Uri uri, IPipeTransportFact… Object[] , Object[] )
  at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
  at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
  at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
  at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc& rpc)
  at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)

错误源于托管代码和非托管代码之间的边界,其中调用了advapi32.dll

[SecurityCritical]
private static SafeCloseHandle GetCurrentProcessToken()

  SafeCloseHandle TokenHandle = (SafeCloseHandle) null;
  if (!UnsafeNativeMethods.OpenProcessToken(UnsafeNativeMethods.GetCurrentProcess(), TokenAccessLevels.Query, out TokenHandle))
    throw System.ServiceModel.FxTrace.Exception.AsError((Exception) new Win32Exception(Marshal.GetLastWin32Error()));
  return TokenHandle;


[DllImport("advapi32.dll", SetLastError = true)]
internal static extern bool OpenProcessToken(IntPtr ProcessHandle, TokenAccessLevels DesiredAccess, out SafeCloseHandle TokenHandle);

网上各种话题都建议去掉元素或者设置impersonate="false"

<system.web>
  <identity impersonate="true"/>
</system.web>

确实,这可以解决我的问题。但是,我不确定这可能会对应用程序 (SharePoint 2016) 产生什么副作用,因此我不愿意简单地删除此属性。

SecurityCritical 属性给了我一些提示,这可能与 .NET 2.0 和 .NET 4.0 之间 CAS 模型的变化有关。该代码已安装到 GAC 中,因此它应该已经在完全信任的情况下运行,但我还是试了一下。

我也尝试将[SecuritySafeCritical] 添加到调用IChannel.Open() 的方法和类中,但无济于事。

我还尝试在程序集上添加[assembly: SecurityRules(SecurityRuleSet.Level1)],因为这应该锁定到 .NET Framework 2.0 安全规则中。

我正在寻找任何其他见解和其他方法来尝试解决此问题。

与其他 Stack 帖子有一些相似之处:How to call net.pipe (named pipe) WCF services while impersonating in a Windows Service,只是没有发生明确的模拟,所以我不确定修复是否适用。

另外需要注意的是,当我尝试调用System.Diagnostics.Process.GetCurrentProcess() 时,会抛出相同的错误。尝试获取当前执行进程的句柄时也会出现该错误。

【问题讨论】:

命名管道 WCF 服务是否托管在 IIS 中?您是否有能力以其他方式托管它(例如自托管或 Windows 服务)? @lesscode 它托管在带有 WAS 激活的 IIS 中。但是,正如我所提到的,错误并非源自服务端;打开频道时它在客户端失败。 (客户端也在 IIS 中)。如果我从控制台应用程序运行客户端,它工作正常。 我的猜测是您的控制台应用程序可以运行提升,而您的 Sharepoint Web 应用程序没有。我认为(我的 WCF 有点生疏)WCF 命名管道只能在与交互式用户相同的登录会话中访问,除非进程可以创建全局(而不是本地)内核对象用于解析管道名称。我会看看我是否可以从前世挖掘出一些更详细的笔记...... 奇怪的是,应用程序池帐户是管理员帐户,而我用来连接的 Windows 帐户也是管理员帐户。当我通过代码进行调试时,HttpContext 用户被报告为管理员帐户。在之前的 3.5 版本(.NET 2.0 运行时)中,这可以正常工作(可能是一些配置差异,我还没有发现?) 啊,我也发现这个响了几声:***.com/questions/3366976/… 【参考方案1】:

我得出的结论是,此问题与 .NET 4.0 中 System.ServiceModel 的内部有关。

最初,我认为这可能与 Server 2016 UAC 或 .NET 4.0/IIS 10 Web 应用程序运行时设置有关(例如 .NET 2.0 与 .NET 4.0 CAS 模型)。我在 .NET 3.5 中创建了一个简单的 Web 应用程序并尝试调用 Process.GetCurrentProcess().Handle。我在新服务器上运行了它,但失败并出现同样的“访问被拒绝”错误。

我将它带到旧服务器(Windows Server 2008 R2、.NET 3.5)并在那里运行,期望它能够正常工作,结果它也失败了。所以我浏览了3.5中System.ServiceModel的源代码,发现没有AppContainerInfo,因此很可能3.5代码根本没有进行相同的Win32 API级别调用。

我的结论是我们之前没有遇到过这个错误,因为旧的 3.0 库不需要从 advapi32.dll 调用 API 或有一些其他机制来创建管道名称。

确实,这是 3.0 中 PipeConnectionInitiator.GetPipeName 的前几行实现:

internal static string GetPipeName(Uri uri)

  string[] strArray = new string[3]
  
    "+",
    uri.Host,
    "*"
  ;
  bool[] flagArray = new bool[2] true, false ;
  for (int index1 = 0; index1 < strArray.Length; ++index1)
  
    for (int index2 = 0; index2 < flagArray.Length; ++index2)
    

这是 4.0 中的前几行:

internal static string GetPipeName(Uri uri, IPipeTransportFactorySettings transportFactorySettings)

  AppContainerInfo appContainerInfo = PipeConnectionInitiator.GetAppContainerInfo(transportFactorySettings);
  string[] strArray = new string[3]
  
    "+",
    uri.Host,
    "*"
  ;
  bool[] flagArray = new bool[2] true, false ;
  string str1 = string.Empty;
  string str2 = (string) null;
  for (int index1 = 0; index1 < strArray.Length; ++index1)
  
    for (int index2 = 0; index2 < flagArray.Length; ++index2)
    
      if (appContainerInfo == null || !flagArray[index2])

所以4.0的实现需要访问权限才能执行OpenProcessToken

如果代码充分隔离,一个选择是使用程序集绑定重定向:

<runtime>
  <assemblyBinding>
    <dependentAssembly>
      <assemblyIdentity name="System.ServiceProcess" publicKeyToken="b77a5c561934e089" culture="neutral" />
      <bindingRedirect oldVersion="4.0.0.0" newVersion="3.0.0.0" />
    </dependentAssembly>            
  </assemblyBinding>
</runtime>

并且只需强制运行时绑定到旧版本。

不幸的是,该应用程序对System.ServiceModel 4.0 有一些依赖,所以我切换起来并不是那么简单。

【讨论】:

以上是关于启动IIS时,为啥提示拒绝访问?的主要内容,如果未能解决你的问题,请参考以下文章

Jmeter保存时,完美解决提示的“拒绝访问”

为啥有些文件拒绝访问

无法启动 IIS Express Web 服务器,无法注册 URL,访问被拒绝

托管到IIS后无法启动浏览器访问被拒绝

VS2013无法启动IIS调试,被拒绝访问

IIS拒绝访问