Как сопоставить учетные данные со сборкой SQLCLR на сервере SQL? - PullRequest
1 голос
/ 15 января 2020

У меня есть сборка CLR на SQL Сервере, который мне нужен для наследования разрешений конкретной учетной записи. Функция CLR в основном просто захватывает веб-страницу и возвращает ее на SQL следующим образом:

    [SqlFunction]
    [return: SqlFacet(MaxSize = -1)]
    public static SqlChars Get(SqlChars H, SqlChars url)
    {
        var client = new WebClient();

        client.Credentials = CredentialCache.DefaultNetworkCredentials;

        AddHeader(H, client);
        return new SqlChars(
                client.DownloadString(
                    Uri.EscapeUriString(url.ToSqlString().Value)
                    ).ToCharArray());
    }

Я хочу, чтобы она могла проходить аутентификацию через NTLM с использованием определенных c учетных данных. Это прекрасно работает в программе C# вне SQL, но в качестве функции CLR она просто возвращает 401 неавторизованных сообщений, потому что DefaultNetworkCredentials принадлежат учетной записи SQL службы сервера (я подтвердил это, установив службу использовать мои учетные данные, и CLR тогда работал отлично)

Насколько я понимаю, способ сделать это - создать Credential на SQL сервере с данными этой учетной записи, поскольку это то, что говорится в документации :

Учетные данные предоставляют способ SQL пользователям проверки подлинности сервера иметь удостоверение личности вне SQL сервера. Это в основном используется для выполнения кода в сборках с набором разрешений EXTERNAL_ACCESS.

Я могу это сделать, но я не могу найти способ сопоставить эти учетные данные со сборкой. Как мне это сделать?

1 Ответ

1 голос
/ 15 января 2020

Я не уверен, что учетные данные на SQL сервере действительно работают таким образом (способ, описанный на этой странице документации). Но даже если бы их можно было использовать для внешних операций через модули SQLCLR, это не было бы путем назначения чего-либо сборке. Учетные данные на SQL сервере сопоставляются с SQL именами входа на сервер. Следовательно, вы должны сопоставить учетные данные с одним или несколькими SQL именами входа сервера, которые будут выполнять модуль на основе SQLCLR.

И, если вам нужна внешняя операция для использования контекста безопасности, отличного от заданного по умолчанию, - SQL Учетная запись службы сервера - тогда вам нужно активировать Олицетворение внутри. NET кода . При этом будет принят контекст безопасности учетной записи Windows, которая выполняет модуль на основе SQLCLR на сервере SQL. SQL Логины сервера не являются учетными записями Windows, поэтому они обычно не могут выполнять олицетворение в коде. NET. Возможно, если сопоставить учетные данные T- SQL и SQL имя входа на сервер, то это будет возможно (Я проверил это, и оно не работает; документация очень неправильная; я отправлю исправление для него на GitHub). Помните, что объекты WindowsIdentity и WindowsImpersonationContext являются одноразовыми, поэтому вам необходимо либо обернуть их в конструкцию using(...){}, либо, по крайней мере, вызвать Dispose() методы в секции finally блока try/catch/finally или try/finally. Если вы используете Windows Auth logins, то вы можете выполнить эту олицетворение, но она будет олицетворять, какой бы логин ни выполнял модуль, который я предполагаю, что это могут быть разные учетные записи (т. Е. Не всегда ваши), поэтому им всем потребуется доступ к внешней ресурс.

Другой вариант - просто ввести учетные данные непосредственно в код. NET через new NetworkCredential(). Это будет работать не только для SQL входов в систему на сервере, но и для подключения отдельной учетной записи как (вы, конечно, могли бы искать учетные данные из списка, чтобы использовать разные учетные записи в зависимости от некоторых условий, но это как минимум позволяет получить доступ к удаленному ресурсу через одну учетную запись).

...