У меня возникла проблема с вызовом службы WCF поверх net.pipe с помощью олицетворения Windows из службы Windows C#.Как вызвать службы WCF net.pipe (named pipe) во время олицетворения в службе Windows
фон
служба считывает из очереди и создает детские приложения доменов, каждый из которых выполняет определенный модуль согласно пункту извлекается из очереди. Мы называем службу Windows «JobQueueAgent», а каждый модуль - «Job». Я буду использовать эти условия в будущем. Задание может быть настроено для работы в качестве указанного пользователя. Мы используем олицетворение внутри домена приложения задания, чтобы выполнить это. Ниже поток логики и учетных данных в службе:
JobQueueAgent (Windows Service - основной пользователь) >> Создать домен работу >> Работа домена (Domain App) >> IMPERSONATE суб пользователя >> Выполнить работу на потоке с олицетворением >> Работа (модуль - подпользователь) >> Логика работы
«Первичный пользователь» и «Субпользователь» являются учетными записями домена с правами на «вход в систему как услугу».
Служба работает на виртуальном сервере под управлением Windows Server 2012 R2.
Ниже приведен код на С # олицетворения Я использую:
namespace JobQueue.WindowsServices
{
using System;
using System.ComponentModel;
using System.Net;
using System.Runtime.InteropServices;
using System.Security.Authentication;
using System.Security.Permissions;
using System.Security.Principal;
internal sealed class ImpersonatedIdentity : IDisposable
{
[PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
public ImpersonatedIdentity(NetworkCredential credential)
{
if (credential == null) throw new ArgumentNullException("credential");
if (LogonUser(credential.UserName, credential.Domain, credential.Password, 5, 0, out _handle))
{
_context = WindowsIdentity.Impersonate(_handle);
}
else
{
throw new AuthenticationException("Impersonation failed.", newWin32Exception(Marshal.GetLastWin32Error()));
}
}
~ImpersonatedIdentity()
{
Dispose();
}
public void Dispose()
{
if (_handle != IntPtr.Zero)
{
CloseHandle(_handle);
_handle = IntPtr.Zero;
}
if (_context != null)
{
_context.Undo();
_context.Dispose();
_context = null;
}
GC.SuppressFinalize(this);
}
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool LogonUser(string userName, string domain, string password, int logonType,int logonProvider, out IntPtr handle);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool CloseHandle(IntPtr handle);
private IntPtr _handle = IntPtr.Zero;
private WindowsImpersonationContext _context;
}
}
Проблема
Некоторые работы необходимы, чтобы сделать net.pipe WCF службы вызовов в другую службу Windows, запущенной на сервере , Вызов net.pipe не работает при запуске под олицетворением.
Вот исключение я получаю в этом сценарии:
Необработанное исключение: System.ComponentModel.Win32Exception: Доступ отказано трассировки стека
Сервер: в System.ServiceModel.Channels.AppContainerInfo .GetCurrentProcessToken() на System.ServiceModel.Channels.AppContainerInfo.RunningInAppContainer() на System.ServiceModel.Channels.AppContainerInfo.get_IsRunningInAppContainer() в System.ServiceModel.Channels.PipeSharedMemory.BuildPipeName (String pipeGuid)
net.pipe успешно, когда он не работает под олицетворения. Вызов net.pipe также преуспевает, когда олицетворяемый пользователь добавляется в группу «Администраторы». Это означает, что есть некоторая привилегия, которую пользователь должен выполнить для вызова, находясь под олицетворением. Мы не смогли определить, какая политика, привилегия или доступ пользователю должны сделать вызов net.pipe при выдаче себя за олицетворение. Недопустимо, чтобы пользователь был администратором.
Это известная проблема? Существует ли конкретное право пользователя на успех? Могу ли я изменить код, чтобы решить эту проблему? Using WCF's net.pipe in a website with impersonate=true, похоже, указывает, что это не будет работать в приложении ASP.NET из-за NetworkService. Не уверен, но это не должно применяться здесь.
Вы говорите, что net.pipe преуспевает, когда вы не выполняете олицетворение; удастся ли это выполнить из обычного приложения (а не службы) в контексте учетной записи пользователя, которую вы пытаетесь выдавать себя за себя? Другими словами, вы уверены, что проблема связана с олицетворением, а не только из-за того, что пользовательская учетная запись не имеет необходимых прав для подключения? –
Кроме того, вы должны попробовать использовать тип интерактивного входа (2), а не тип входа в систему (5). Я не думаю, что это будет иметь какое-то значение, но я не уверен. –
Я могу воссоздать проблему в консольном приложении. К сожалению, интерактивный вход в систему не работает. – cruikshj