У нас есть устаревший код веб-приложения, который мы обновляем и переносим в среду выполнения .NET 4.0.
Код находится в библиотеке классов и подключается к конечной точке именованного канала с помощью WCF.
Когда я инициирую соединение из консольного приложения, все работает нормально.
Когда я инициирую соединение из веб-приложения, я получаю исключение:
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 подсказал мне, что, возможно, это связано с изменением модели CAS между .NET 2.0 и .NET 4.0. Код установлен в GAC, поэтому он уже должен работать с полным доверием, но я все равно попробовал.
Я также пытался добавить [SecuritySafeCritical] к методу и классу, который вызывает IChannel.Open(), но безрезультатно.
Я также попытался добавить [assembly: SecurityRules(SecurityRuleSet.Level1)] в сборку, так как это должно соответствовать правилам безопасности .NET Framework 2.0.
Я ищу любую дополнительную информацию и другие методы, чтобы попытаться решить эту проблему.
Есть некоторое сходство с этим другим сообщением о стеке: -a-windows">Как вызывать службы WCF net.pipe (named pipe) во время олицетворения в службе Windows, за исключением того, что явное олицетворение не происходит, поэтому я не уверен, что исправление применимо.
Дополнительным примечанием является то, что когда я пытаюсь вызвать System.Diagnostics.Process.GetCurrentProcess(), возникает та же ошибка. Ошибка также возникает при попытке получить дескриптор текущего исполняемого процесса.
HttpContextсообщается как учетная запись администратора. В предыдущей версии 3.5 (среда выполнения .NET 2.0) это работало нормально (возможно, какая-то разница в конфигурации, которую я еще не нашел?) - person Charles Chen   schedule 07.05.2018advapi32.dll. Я попытался использоватьOpenProcessToken, чтобы заставить токен процесса олицетворяться, и получил ту же ошибку. - person Charles Chen   schedule 07.05.2018