Я хочу, чтобы функция CLR выполнялась с указанием c windows идентификатора при вызове из SQL Заданий агента сервера. С этой целью оператор SQL, вызывающий функцию, имеет вид:
execute as user='domain\username'
select database.schema.function()
revert
Сама функция, ради аргументов, может просто выглядеть примерно так:
[SqlFunction(DataAccess = DataAccessKind.Read)]
[return: SqlFacet(MaxSize = -1)]
public static SqlChars GetIdentityInformationImpersonated()
{
WindowsIdentity clientId;
WindowsImpersonationContext impersonatedUser;
string currentUser;
clientId = SqlContext.WindowsIdentity;
impersonatedUser = clientId.Impersonate();
currentUser = WindowsIdentity.GetCurrent().Name;
impersonatedUser.Undo();
return new SqlChars(currentUser);
}
Это бросает исключение:
A. NET Ошибка структуры произошла во время выполнения пользовательской подпрограммы или агрегата «GetIdentityInformationImpersonated»: System.NullReferenceException: ссылка на объект не установлена для экземпляра объекта. System.NullReferenceException: at WinIdentityDebugging.IdentityResults.GetIdentityInformationImpersonated ()
Что означает, что SqlContext.WindowsIdentity
равно нулю. Теперь в inte rnet есть ссылки, утверждающие, что такая вещь невозможна, например ...
... здесь ...
Имейте в виду, что олицетворение SQLCLR не работает с олицетворенными контекстами (EXECUTE AS)
... и здесь ...
попытка получить объект SqlContext.WindowsIdentity является олицетворенным контекстом безопасности, в настоящее время возвращает ноль и для этого делает c 'd.
... и здесь ...
Если выполнение происходит в контексте логина «Выполнение от имени» (оператор непосредственно или некоторый модуль, помеченный им), SqlContext.WindowsIdentity будет иметь значение null, если логин не является sysadmin. В этом случае SqlContext.WindowsIdentity возвращает идентификатор, под которым выполняется процесс сервера.
Но все эти ссылки довольно старые, и я не могу найти таких ограничений в реальной документации. Например, страница SqlContext.WindowsIdentity указывает только на то, что она является нулевой для SQL вызывающих абонентов:
Экземпляр WindowsIdentity, представляющий Windows идентификатор вызывающего абонента, или нулевой если клиент был аутентифицирован с использованием SQL аутентификации сервера.
Так что я надеюсь, что есть способ достичь этого.
Возможно ли такое? Или мне не повезло?