We have some legacy web application code which we are updating and porting into a .NET 4.0 runtime.
The code is in a class library and connects to a named pipe endpoint using WCF.
When I initiate the connection from a console application, everything works fine.
When I initiate the connection from a web application, I receive an exception:
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)
The error originates at a boundary between the managed code and unmanaged code where there is a call into 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);
Various topics on the web suggest removing the element or setting impersonate="false"
:
<system.web>
<identity impersonate="true"/>
</system.web>
And indeed, this works to fix my issue. However, I'm not certain what side effects this may have on the application (SharePoint 2016) so I'm reluctant to simply remove this attribute.
The SecurityCritical
attribute gave me some hints in that perhaps this is related to the change in the CAS model between .NET 2.0 and .NET 4.0. The code is installed into the GAC so it should be running under full trust already but I gave it a shot anyways.
I have also tried adding [SecuritySafeCritical]
to the method and the class which invokes the IChannel.Open()
to no avail.
I also tried adding [assembly: SecurityRules(SecurityRuleSet.Level1)]
on the assembly as this should lock into the .NET Framework 2.0 security rules.
I'm looking for any additional insight and other methods to try to resolve this issue.
There is some similarity to this other Stack post: How to call net.pipe (named pipe) WCF services while impersonating in a Windows Service except that there is no explicit impersonation occurring so I'm not certain that the fix would apply.
An additional note is that when I try to call System.Diagnostics.Process.GetCurrentProcess()
, the same error is thrown. The error also originates when trying to get a handle on the current executing process.