Выполнение хранимой процедуры, которая обращается к другому экземпляру SQL

8

Прошу прощения, если этот вопрос повторяет другой, уже заданный. Я искал несколько часов и не нашел того, который подходит моей ситуации.

Желаемый результат

Пользователь, использующий аутентификацию SQL, имеет права на выполнение для Database1 на Server1 (экземпляр по умолчанию), и это все. Пользователь выполняет хранимую процедуру, которая в рамках своего процесса обращается к базе данных 2 на сервере Server1 \ Instance2. Я хотел бы, чтобы это было безопасно и просто (оба важны).

Больше информации

Мои учетные данные Windows имеют доступ к обоим экземплярам (которые находятся на одном сервере). Поэтому я могу без труда выполнить хранимую процедуру под своим логином. Однако я не хочу предоставлять пользователю мой уровень доступа. Мне также нужно использовать логин SQL, так как пользователь не будет в домене.

Я хотел бы предоставить хранимой процедуре мой уровень доступа только для этой процедуры. Поскольку я являюсь системным администратором, это даст пользователю все необходимое для этой процедуры. Если бы я заставил это работать, я бы, вероятно, создал учетную запись именно для этой цели, а не использовал мою, но в любом случае это было бы безопасно, так как я контролирую, что делает хранимый процесс.

Я попытался поместить оператор «WITH EXECUTE AS» в свой хранимый процесс, но не смог получить его, чтобы получить информацию для входа в Windows. Когда я вставлю его, я получу следующую ошибку при компиляции хранимого процесса:

Невозможно выполнить от имени пользователя домен \ jdoe, так как он не существует или у вас нет разрешения.

Как я уже сказал, на обоих серверах пользователь sysadmin, поэтому я не уверен, что ему еще нужно.

Я посмотрел на следующее:

  • ДОВЕРЕННЫЙ - я бы предпочел не выставлять свою базу данных, и это выглядит страшно
  • Связанный сервер - я не хочу давать дополнительные разрешения. Я не доверяю другой базе данных иметь доступ к моей базе данных, и я не доверяю своей базе данных иметь доступ ко всей другой базе данных.
  • Сертификаты - это кажется сложным и сложным. Если я не смогу найти очень простой способ сделать это и поддерживать его, я не уверен, что это стоит того.
  • Цепочка владения - Опять страшно. Похоже, что это вызывает больше проблем безопасности, когда моя цель - предотвратить проблемы безопасности.
  • Зеркальный пользователь - я даже создал одного (очевидно, другого SID) пользователя на другом экземпляре сервера и дал ему тот же пароль. Нет идти

Я чувствую, что упускаю что-то очевидное, но я не уверен, что это такое. Так как я целый день бился об стену, я, наверное, слишком близко, чтобы это увидеть. Я был бы очень признателен, если бы кто-то здесь мог помочь мне или указать мне правильное направление. Я скажу, что я прочитал много статей MSDN (мальчик, я ненавижу их - они, кажется, никогда не говорят мне то, что я хочу знать). То, что я действительно хотел бы, является простым, легким для того, чтобы следовать за учебником, который ведет меня через, как сделать это. Если не считать этого, даже общее указание направления, в котором я должен идти, было бы полезно.

IAmTimCorey
источник

Ответы:

3

Попробуйте вместо этого использовать EXECUTE AS LOGIN = 'DOMAIN \ username' и посмотрите, работает ли это.

mrdenny
источник
Я пробовал это, но эта команда, очевидно, не предназначена для хранимой процедуры.
IAmTimCorey
Он должен нормально работать внутри хранимой процедуры. У вашей учетной записи есть свой собственный логин или вы получаете права через членство в группе?
Мрденный
Моя учетная запись имеет собственный логин с правами системного администратора. Он также обладает правами администратора домена через членство в группе, так что он должен дать мне все, что мне нужно, и он дает, когда я вошел в систему с использованием моих учетных данных Windows. Однако я обнаружил две вещи. Во-первых, если я использую приведенный выше код в операторе WITH хранимого процесса, возникает синтаксическая ошибка. Если я помещу это в утверждение, оно будет работать внутри одного экземпляра, но не между экземплярами.
IAmTimCorey
3

Взгляните на использование EXECUTE AS+ Trustworthy. Вы можете установить его так, чтобы он вызывался в хранимой процедуре, если пользователю b предоставлен доступ и две базы данных доверяют друг другу.

Этот блог парней должен ответить или предоставить все, что вам нужно. http://www.sommarskog.se/grantperm.html#EXECAScrossdb

использование свойства базы данных TRUSTWORTHY для управления доступом к ресурсам вне области исходной базы данных

http://msdn.microsoft.com/en-us/library/ms188304%28v=sql.90%29.aspx

SoftwareCarpenter
источник
Проблема, с которой я сталкиваюсь, заключается в том, что Trustworthy устанавливает доверительные отношения между двумя базами данных. Это может быть использовано системными администраторами с обеих сторон. Я не хочу этого Я пытаюсь ограничить права одного человека. Если я в конечном итоге дам другому человеку еще больше разрешений, это не будет хорошей вещью. Спасибо хоть.
IAmTimCorey
Обратите внимание, что отдельные владельцы не обязательно должны быть физическими лицами, но это может быть общий логин для каждой базы данных. Вам не нужно предоставлять всю базу данных более. Если вы не доверяете системным администраторам в другой базе данных, настаивайте на подписи сертификата.
SoftwareCarpenter
Вы упомянули, что натолкнулись на ссылку sommarskog.se/grantperm.html в своем ответе ниже. Это тот же блог, который я разместил в ответе, который я предложил. «Этот блог, ребята, должен ответить или предоставить все, что вам нужно. Sommarskog.se/grantperm.html#EXECAScrossdb « Возможно, вы просто ссылались на других. Я согласен, что это хороший блог и читаю. Удачи!
SoftwareCarpenter
Да, извините, я забыл сказать, что ссылка пришла от вас. Это был хороший ресурс. Спасибо за вашу помощь.
IAmTimCorey
2

После подробного прочтения этой темы и проведения ряда экспериментов я считаю, что пришел к выводу по этому вопросу. Оператор EXECUTE AS не предназначен для работы между экземплярами без существенных последствий для безопасности. То, на что я надеялся, - это способ сообщить моей процедуре, под каким удостоверением Windows я хочу работать, поскольку удостоверение Windows может иметь доступ к нескольким ресурсам на нескольких серверах. Однако даже после игры с кучей разных настроек стало очевидно, что мне придется ослабить другие меры безопасности, чтобы позволить хранимой процедуре выдавать себя за меня.

Похоже, не так много информации о процедурах между экземплярами или между серверами. Я полагаю, что причина этого заключается в том, что это влияет на безопасность и производительность. Тем не менее, я считаю, что есть случаи, когда это важно, и кажется, что решения для этого являются сложными и очень специфичными для сценария. Я наткнулся на хорошую статью, которая помогла мне хотя бы понять некоторые из моих вариантов. Он не был сосредоточен на доступе между экземплярами, но дал мне подсказки, которые я искал. Я бы посоветовал вам проверить это:

http://www.sommarskog.se/grantperm.html

Я все еще был бы заинтересован в других решениях этой проблемы, но мое решение сейчас двоякое. Во-первых, если мне абсолютно необходим доступ к двум базам данных с помощью одной хранимой процедуры, я должен использовать логин Windows. Однако я избегаю этого всякий раз, когда это возможно, поскольку это вызывает проблемы с производительностью (блокировка нескольких серверов, сетевые сложности, невозможность оптимизировать запрос и т. Д.). Во-вторых, я передаю данные из каждой базы данных через отдельные вызовы, специфичные для базы данных. Это означает, что я возвращаю данные клиенту перед их объединением. Это не так эффективно и не так чисто, как хотелось бы, но, похоже, это самое безопасное решение.

IAmTimCorey
источник
1

Если вам нужен доступ к объектам базы данных между двумя экземплярами SQL-сервера, я бы порекомендовал один из следующих:

  1. Создайте и используйте связанный сервер между двумя экземплярами с соответствующим разрешением для доступа к объекту в целевом (удаленном) экземпляре.
  2. Используйте SSIS и вызовите пакет из исходного экземпляра SQL Server. В зависимости от того, какая версия SQL Server используется, у вас может быть задание агента SQL (не запланированное для запуска, но вызываемое хранимой процедурой), или использовать SSISDB для вызова пакета SSIS, который будет обращаться к объекту базы данных на удаленном экземпляре.
  3. Переместите логику на средний уровень (или на сторону клиентского приложения)
  4. Создайте CLR для доступа к объекту удаленной базы данных. Я бы, вероятно, использовал CLR для доступа к серверу удаленного экземпляра и запустил бы выполнение хранимой процедуры. Вам нужно будет предоставить учетную запись, с которой исходный экземпляр SQL Server выполняется под доступом к удаленному экземпляру SQL Server.
Том
источник