Переключение контекста выполнения внутри триггера входа в систему
-
01-10-2019 - |
Вопрос
У меня есть база данных, называемая MyDB в экземпляре Express Microsoft SQL Server 2008, используя аутентификацию смешанного режима. Приложение с использованием MyDb базы данных в настоящее время подключается с помощью аутентификации Windows, используя учетные данные Windows текущего пользователя. Этот логин является членом «Public» сервера, и имеет сопоставку пользователем в базе данных MyDB. Этот пользователь базы данных является членом ролей базы данных db_datareader и db_datawriter.
Что мне бы хотелось, что когда приложение подключится, у него есть разрешения для чтения и записи в MyDB. Но когда другое приложение соединяется с использованием того же входа в систему, его следует разрешить только для чтения.
Моя мысль заключалась в том, что я бы создал триггер входа в систему, который проверил бы название приложения частью соединительной строки и основываясь на этом решить, следует ли переключаться контекст выполнения. (Для записи, я знаю, что никоим образом не в безопасности, чтобы полагаться на имя приложения строки подключения, и что она очень легко обойти. Целью здесь не защищает базу данных, но чтобы помочь пользователям избежать изменений Данные, когда они подключаются с использованием другого приложения, например, Microsoft Excel)
Я создал новый логин под названием «MyApp_Reader» сопоставлен с пользователем в базе данных MyDB, которая является членом db_datareader.
Затем я попробовал создать триггер входа со следующим TSQL:
CREATE TRIGGER CheckUser
ON ALL SERVER
AFTER LOGON AS
BEGIN
IF APP_NAME() <> 'My Application Name'
BEGIN
EXECUTE AS LOGIN = 'myapp_reader' WITH NO REVERT
END
END
Но, к сожалению, это не работает. Когда я пытаюсь подключиться, я получаю следующую ошибку:
Ошибка входа в систему для входа в систему «MyComputer myWindowSusername» из-за выполнения запуска.
Изменена контекст базы данных на «Master».
Изменена настройка языка для us_eglish. (Microsoft SQL Server, ошибка: 17892)
И когда я смотрю в ErrorLog, он говорит:
Ошибка: 15590, тяжесть: 16, штат: 1.
Можно использовать только параметры «нет возврата» или «Cookie» с оператором «Выполнить как» на уровне ADHOC.
Ошибка: 17892, тяжесть: 20, штат: 1.
Ошибка входа в систему для входа в систему «MyComputer myWindowSusername» из-за выполнения запуска. [Клиент: xxx.xxx.xxx.xxx
Очень эта ошибка означает, что я не могу навсегда изменить контекст выполнения в триггере входа?
Решение
Я не думаю, что это возможно изменить контекст выполнения для всего сеанса. Вы можете создать триггер DML для вставки, обновления и удаления для каждой таблицы / представления в вашей базе данных, который делает откат для определенного App_name (). Вы можете написать процедуру для автоматизации создания всех этих триггеров.
В качестве альтернативы, если у вас есть возможность иметь такие приложения, как Excel, подключающиеся через связанный сервер, вы можете изменить контекст выполнения в этот момент. И создайте триггер входа в систему, который возвращает соединение, если пользователи пытаются подключаться через Excel или другие приложения непосредственно на сервер.
Другие советы
Предполагая, что у вас есть контроль над приложением и может изменять его, то роли приложений будут делать именно то, что вы хотите. См. SP_Set Approle в книгах онлайн, чтобы начать.
Вы не можете сделать это в моде, которую вы хотите.
- Пользовательское соединение имеет одни и те же учетные данные во всем, за исключением некоторых конкретных областей, использующих execute AS.
- Вы поняли, что не можете полагаться на App_name () или Host_name () для обнаружения, когда кто-то подключается по-другому, что означает, что триггер отката на таблицу не может полагаться там
- Ваше приложение опирается на прямую таблицу
Некоторые варианты я могу думать о ...
- Ваше приложение использует хранимые программы, пользователи прочитали доступ только к таблицам
- Используйте SET CONTEXT_INFO в своем приложении, чтобы установить «секретную» ключ для отката триггеров
- Измените свое приложение для использования сервисной учетной записи / - это служба Windows / etc и Proxies, имеющее имя пользователя (как будет бы сделать веб-страницу)
- ... или некоторые перестановки Тероф
Вам действительно нужно сначала принять решение о том, как организовать и управлять учетными данными.
Если вы используете SP_Set Approle, который обойдут аутентификацию Windows и обеспечивает доступ к этому приложению для любого пользователя. Если это то, что вы действительно хотите сделать, то, если приложение - это сервер, создайте учетную запись пользователя для этого приложения и запустить его под учетными данными пользователями.
Если это клиентское приложение, затем сделайте веб-службу, которая будет читать только и отправлять конкретные данные, которые требуется приложение и запускает эту веб-службу под новой учетной записью. Затем в IIS7 вы можете поставить ACL на сам веб-сервис, чтобы она все еще была защищена.
Также, если это приложение не доверяется чистым и знают, что он делает, то запросить, чтобы он должен был быть пересмотренным кодом, прежде чем он разрешено касаться SQL Server. Если это ваше собственное приложение, то начните доверять себе :-)