У нас есть некоторый устаревший код веб-приложения, который мы обновляем и переносим в среду выполнения .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.
Я ищу какие-либо дополнительные сведения и другие способы, чтобы попытаться решить эту проблему.
Существует некоторое сходство с этим другим постом в стеке: Как вызывать службы WCF net.pipe (именованный канал) при олицетворении в службе Windows , за исключением того, что не происходит явного олицетворения, поэтому я не уверен, что исправление будет применяться.
Дополнительное замечание: при попытке вызвать System.Diagnostics.Process.GetCurrentProcess()
выдается та же ошибка. Ошибка также возникает при попытке получить дескриптор текущего выполняющегося процесса.