启动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时,为啥提示拒绝访问?的主要内容,如果未能解决你的问题,请参考以下文章