Расширение олицетворения базы данных с помощью инструкции EXECUTE AS

SQL Server поддерживает явное олицетворение другого участника с помощью автономной инструкции EXECUTE AS, а также неявное олицетворение с помощью предложения EXECUTE AS в модулях. Олицетворение участников уровня сервера и имен входа выполняется с помощью автономной инструкции EXECUTE AS путем использования инструкции EXECUTE AS LOGIN. Олицетворение участников уровня базы данных и имен пользователей выполняется с помощью автономной инструкции EXECUTE AS путем использования инструкции EXECUTE AS USER.

Неявные олицетворения, выполняемые через предложение EXECUTE AS в модулях, олицетворяют указанного пользователя или имя учетной записи на уровне базы данных или сервера. Олицетворение зависит от уровня модуля: это либо модуль уровня базы данных (например, хранимая процедура или функция), либо модуль уровня сервера (например, триггер уровня сервера).

Основные сведения об области олицетворения

При олицетворении участника с помощью инструкции EXECUTE AS LOGIN или с помощью предложения EXECUTE AS внутри модуля области сервера областью олицетворения является весь сервер. Это означает, что после смены контекста становится доступен любой ресурс внутри сервера, к которому имеет доступ олицетворенное имя входа учетной записи.

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

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

Например, рассмотрим две базы данных на одном сервере, принадлежащие разным владельцам. Database1 принадлежит Бобу, а Database2 — Фреду. Боб не хочет, чтобы у Фреда был доступ к его базе данных, и наоборот. Как владелец Database1 Боб может создать в своей базе данных пользователя для Фреда, и, имея все разрешения внутри Database 1, Боб может олицетворить пользователя Фред. Однако накладываемые SQL Server ограничения безопасности не позволяют Бобу получить доступ к базе данных Фреда в контексте олицетворения. Без наличия этих ограничений по умолчанию Боб получил бы анонимный доступ к данным Фреда. Именно поэтому область олицетворений уровня базы данных ограничена по умолчанию базой данных.

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

Рассмотрим случай маркетингового приложения, которое вызывает хранимую процедуру с именем GetSalesProjections в базе данных Marketing. В этой хранимой процедуре задан переключатель контекста выполнения. Хранимая процедура запрашивает в базе данных Sales сведения о продажах из таблицы SalesStats. По умолчанию этот сценарий не сработает, поскольку контекст выполнения, установленный внутри одной базы данных, является недопустимым вне этой базы данных. Однако разработчики маркетингового приложения не предоставляют пользователям этого приложения прямой доступ к базе данных Sales или права на какой-либо объект внутри нее. Идеальным решением будет олицетворение пользователя, обладающего необходимыми разрешениями в базе данных Sales, с помощью предложения EXECUTE AS в хранимой процедуре. Однако текущие ограничения по умолчанию это запрещают. Таким образом, вопрос состоит в том, как разработчики могут решить эту проблему.

В SQL Server можно выборочно расширять текущую область олицетворения базы данных путем настройки доверительной модели отношений между двумя базами данных. Однако, перед тем как знакомиться с описанием этой модели и способами выборочного расширения области олицетворения, необходимо разобраться в принципах проверки подлинности и понять роль средств проверки подлинности в SQL Server.

Основные сведения о средствах проверки подлинности

Проверка подлинности — это процесс, посредством которого участник доказывает системе свою подлинность. Средство проверки подлинности — это объект, выполняющий проверку подлинности отдельного участника, то есть подтверждающий его подлинность. Например, при подключении к SQL Server подлинность имени входа, заданного для текущего соединения, проверяется экземпляром SQL Server.

Рассмотрим случай, когда пользователь явно переключает контекст на уровне сервера с помощью инструкции EXECUTE AS LOGIN. Для этого обязательно наличие разрешений на олицетворение на уровне сервера. Эти разрешения позволяют участнику, вызвавшему инструкцию EXECUTE AS LOGIN, олицетворять указанное имя входа в пределах всего экземпляра SQL Server. Следовательно, эта инструкция позволяет ему имитировать вход в систему под олицетворенным именем входа. Владелец разрешений области уровня сервера — sysadmin, который является обладателем экземпляра SQL Server. При олицетворении уровня сервера средство проверки подлинности — это sysadmin или сам экземпляр SQL Server.

Однако рассмотрим случай, когда контекст устанавливается инструкцией EXECUTE AS USER или предложением EXECUTE AS в модуле области базы данных. В этих случаях проверяются разрешения на олицетворение внутри области базы данных. Область по умолчанию разрешений IMPERSONATE для пользователей — это сама база данных, владельцем которой является dbo. Кроме того, владелец базы данных является средством проверки подлинности этих олицетворений. Именно владелец базы данных устанавливает подлинность олицетворенного пользователя и подтверждает его подлинность. Поскольку владельцу базы данных принадлежит вся база данных, олицетворенный контекст считается подлинным внутри всей указанной базы данных. Однако вне этой базы данных олицетворенный контекст является недопустимым.

Применение средств проверки подлинности

С помощью средств проверки подлинности проверяется допустимость установленного контекста внутри определенной области. Чаще всего средствами проверки подлинности являются системный администратор (SA), экземпляр SQL Server, а также dbo (при работе с базами данных). Средство проверки подлинности — это, в конечном итоге, владелец области, внутри которой установлен контекст для отдельного пользователя или имени входа. Сведения о средстве проверки подлинности получаются из информации о маркере, поддерживаемой для имени входа и пользователя, и доступны через представления sys.user_token и sys.login_token. Дополнительные сведения см. в разделе Основные сведения о контексте выполнения.

ПримечаниеПримечание

Если из представления маркеров не возвращаются сведения о средстве проверки подлинности, то средством проверки подлинности является экземпляр SQL Server. Это выполняется, если отсутствует переключение контекста или олицетворение осуществляется на уровне сервера.

Контекст выполнения, принадлежащий владельцу области как ее средству проверки подлинности, действителен внутри всей этой области. Это обусловлено тем, что владелец области, например базы данных, является неявно доверенным для всех сущностей внутри области. Контекст так же действителен в других областях, например в других базах данных или непосредственно экземплярах SQL Server, в которых средство проверки подлинности является доверенным. Следовательно, действительность олицетворенного пользовательского контекста вне области базы данных зависит от того, является ли средство проверки подлинности доверенным для контекста внутри целевой области. Эта «доверенность» устанавливается путем выдачи средству проверки подлинности разрешения AUTHENTICATE, если целевая область является другой базой данных, или путем выдачи разрешения AUTHENTICATE SERVER, если целевая область — экземпляр SQL Server.

Расширение области олицетворения

Для расширения области олицетворения от текущей базы данных до целевой области, например до другой базы данных или экземпляра SQL Server, необходимо выполнить следующие условия.

  • Средство проверки подлинности должно быть доверенным в целевой области.

  • База данных-источник должна быть помечена как заслуживающая доверия.

Доверие средству проверки подлинности

На основании предыдущего примера с базами данных Sales и Marketing ниже показано, как хранимая процедура GetSalesProjections в базе данных Marketing обрабатывает данные из таблицы SalesStats в базе данных Sales. Хранимая процедура содержит предложение EXECUTE AS USER MarketingExec. Владельцем базы данных Sales является SalesDBO, владельцем базы данных MarketingMarketingDBO.

Инструкция EXECUTE AS переключает контекст выполнения модуля

Если хранимая процедура GetSalesProjections вызывается пользователем, то предложение EXECUTE AS неявно переключает контекст выполнения хранимой процедуры с вызвавшего пользователя на пользователя MarketingExec. Средством проверки подлинности для этого контекста является MarketingDBO — владелец базы данных Marketing. По умолчанию процедура имеет доступ к любым ресурсам внутри базы данных Marketing, к которой разрешен доступ пользователю MarketingExec. Однако, чтобы получить доступ к таблице базы данных Sales, база данных Sales должна доверять средству проверки подлинности MarketingDBO.

Для этого в базе данных Sales нужно создать пользователя с именем MarketingDBO, сопоставленным с именем входа MarketingDBO, и выдать пользователю разрешение AUTHENTICATE в базе данных Sales. В результате внутри базы данных действительным является любой контекст выполнения, средство проверки подлинности которого обладает этим разрешением. Поскольку средству проверки подлинности MarketingDBO предоставлено разрешение AUTHENTICATE в базе данных Sales, контекст для пользователя MarketingExec, установленный предложением EXECUTE AS в хранимой процедуре GetSalesProjections в базе данных Marketing, является доверенным в базе данных Sales.

В этом примере показано расширение области олицетворения, обеспечивающее доступ к объектам во внешней базе данных, однако, кроме того, область олицетворения можно расширить до экземпляра SQL Server. Например, для процедуры, создающей имя входа, то есть выполняющей действие уровня сервера, которое требует наличия разрешений уровня сервера, разрешение AUTHENTICATE SERVER должно быть предоставлено средству проверки подлинности контекста. Смысл этого заключается в том, что любой контекст, средство проверки подлинности которого обладает разрешением AUTHENTICATE SERVER, является доверенным во всем экземпляре SQL Server**,** как если бы контекст непосредственно вошел в экземпляр SQL Server.

Доверие базе данных

В SQL Server доверительная модель продвинулась на шаг вперед в обеспечении дополнительной безопасности и гранулярности в расширении области олицетворения уровня базы данных. Как вариант, доверительные отношения между целевой областью и средством проверки подлинности контекста можно устанавливать с помощью разрешения AUTHENTICATE, но, кроме того, можно определить, доверяет ли экземпляр SQL Server базе данных-источнику и ее содержимому.

Предположим, что участник MarketingDBO является владельцем другой базы данных с именем Conference. Предположим также, что владельцу базы данных с именем MarketingDBO нужно, чтобы контексты выполнения, указанные внутри базы данных Marketing, обладали доступом к ресурсам в базе данных Sales. Однако при этом у контекстов, установленных в базе данных Conference, не должно быть доступа к базе данных Sales.

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

  1. Оно уменьшает опасность, исходящую от подключенных к экземпляру SQL Server баз данных, которые могут содержать опасные модули, выполняемые в контексте пользователя с обширными правами доступа.

    Для этого подключенные базы данных по умолчанию не помечаются как заслуживающие доверия. Кроме того, для доступа к ресурсам вне базы данных с помощью потенциально опасных модулей необходимо, чтобы база данных была помечена как заслуживающая доверия. Свойство TRUSTWORTHY в базе данных могут задавать только члены предопределенной роли сервера sysadmin.

  2. Это позволяет администратору экземпляра SQL Server выявлять среди баз данных, принадлежащих одному владельцу (который является доверенным средством проверки подлинности в некоторой области), те базы данных, которым следует предоставить доступ к внешним ресурсам, и те, которым его предоставлять не следует.

Именно для этого предназначено свойство TRUSTWORTHY. Например, предположим, что олицетворенные контексты из базы данных Database 1 должны быть доверенными, тогда как контексты из другой базы данных, Database 2, не должны быть доверенными, и все они принадлежат одному владельцу, который является доверенным средством проверки подлинности целевой области. Свойству TRUSTWORTHY можно присвоить значение ON для Database 1 и OFF для Database 2; таким образом, модули в Database 2 не будут иметь доступа к ресурсам вне этой базы данных.

Ниже приведен пример управления доступом к ресурсам вне области базы данных-источника с помощью свойства TRUSTWORTHY. Пользователь MarketingDBO обладает разрешениями AUTHENTICATE в базе данных Sales и является владельцем баз данных Marketing и Conference. Хранимая процедура GetSalesProjections в базе данных Marketing может успешно обращаться к базе данных Sales, поскольку она соответствует двум требованиям безопасности: средство проверки подлинности MarketingDBO является доверенным в целевой области, а база данных-источник Marketing заслуживает доверия. Попытки обратиться к базе данных Sales из базы данных Conference запрещаются, поскольку при этом выполняется только одно требование: средство проверки подлинности MarketingDBO является доверенным в целевой области.

Управление доступом базы данных к внешним ресурсам

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

Сертификаты и асимметричные ключи в качестве средств проверки подлинности

Чтобы расширить доступ олицетворения контекста внутри базы данных до ресурсов вне области базы данных, следует использовать владельца базы данных в качестве средства проверки подлинности. Для этого владелец базы данных должен быть доверенным для внешнего ресурса, кроме того, база данных должна сама по себе заслуживать доверия. Впрочем, этот подход неявно подразумевает, что если владелец доверенной базы данных обладает разрешениями AUTHENTICATE или AUTHENTICATE SERVER в целевой области и вызывающая база данных заслуживает доверия, то любой олицетворенный контекст, установленный в этой базе данных, действителен во всей целевой области, которая доверяет владельцу базы данных.

Может потребоваться уровень доверия с более высокой гранулярностью. Предположим, что необходимо доверять только небольшому числу модулей в базе данных-источнике, при этом доступ к целевому ресурсу осуществляется с помощью предложения EXECUTE AS, а база данных-источник является доверенной не целиком. Например, допустим, что пользователю SalesDBO нужно установить доступ хранимой процедуры GetSalesProjections к таблице SalesStats только от имени пользователя MarketingExec, но при этом у любого другого пользователя базы данных Marketing с правами на олицетворение MarketingExec не должно быть доступа к базе данных Sales. Для этого недостаточно сделать пользователя MarketingDBO доверенным и пометить базу данных Marketing как заслуживающую доверия. Для выполнения этого требования доверительная модель обеспечивает дополнительный уровень гранулярности, позволяя использовать в качестве средств проверки подлинности сертификаты или асимметричные ключи. Это дает техническое преимущество, обеспечиваемое электронной подписью. Дополнительные сведения об электронной подписи см. в разделе ADD SIGNATURE (Transact-SQL).

Применение подписей

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

Подписанный модуль становится доверенным после выдачи разрешения AUTHENTICATE или AUTHENTICATE SERVER пользователю в целевой области, сопоставленной с сертификатом или асимметричным ключом.

Таким образом, контекст выполнения, установленный внутри модуля, подписанного с помощью доверенного сертификата, действителен в целевой области, в которой является доверенным этот сертификат.

Например, допустим, что процедура GetSalesProjections подписана с помощью сертификата с именем C1. Сертификат C1 должен существовать в базе данных Sales, с сертификатом C1 должен быть сопоставлен пользователь, например CertUser1. Пользователь CertUser1 обладает разрешениями AUTHENTICATE в базе данных Sales.

При вызове процедуры проверяется подлинность процедуры (не была ли она подделана в момент подписания процедуры). Если подпись заверена, то для контекста, который устанавливается в модуле предложением EXECUTE AS, в качестве средства проверки подлинности используется C1. Если подпись не проходит проверку, то средство проверки подлинности не добавляется в лексему и попытка доступа к внешним ресурсам завершается неуспешно.

В следующем примере показано управление доступом к ресурсам вне области исходной базы данных с помощью подписанного модуля. Процедура GetSalesProjections в базе данных Marketing подписана с помощью сертификата C1. Сертификат C1 существует в базе данных Sales, с ним сопоставлен пользователь CertUser. Пользователь CertUser1 обладает разрешениями AUTHENTICATE в базе данных Sales.

Сертификат для ограничения доступа к базе данных

Доверие этому средству проверки подлинности проверяется аналогично проверке, выполняемой, когда владелец базы данных является средством проверки подлинности. Таким образом, это проверка разрешений AUTHENTICATE SERVER или AUTHENTICATE. Однако поскольку доверие устанавливается на гранулярном уровне и модуль нельзя изменить без изменения подписи, то нет необходимости проверять свойство TRUSTWORTHY в базе данных.

Это уменьшает опасность от подключенных баз данных с вредоносным кодом. Атакующий будет вынужден подписать модуль закрытым ключом, который соответствует уже доверенному сертификату. Однако атакующий не имеет доступа к этому ключу. Кроме того, если существующий доверенный модуль будет изменен, либо если будет создан новый модуль, то он не будет иметь действительной доверенной подписи.

Дополнительные сведения см. в разделе Подписание модулей (компонент Database Engine).

Правила расширения области олицетворения базы данных

В итоге область олицетворения контекста, установленного внутри базы данных, можно расширить на другие области тогда и только тогда, когда выполняются следующие условия:

  • Средство проверки подлинности (владелец базы данных, сертификат или асимметричный ключ), с помощью которого подписан модуль, должен быть доверенным в целевой области. Для этого нужно предоставить разрешения AUTHENTICATE или AUTHENTICATE SERVER участнику, сопоставленному с владельцем базы данных, сертификатом или ассиметричным ключом.

  • Если средством проверки подлинности является владелец базы данных, то база данных-источник должна быть помечена как заслуживающая доверия. Для этого свойству базы данных TRUSTWORTHY следует присвоить значение ON.

Выбор механизма доверия в зависимости от выполняемой задачи

Как механизм на основе владельца базы данных, так и механизм на основе подписей имеют свои достоинства и недостатки. Какой из механизмов лучше — зависит от поставленных задач и рабочей среды.

Подход к установлению доверия, основанный на владельце базы данных

Достоинства и недостатки этого подхода:

  • Не требует вникать в суть таких криптографических понятий, как сертификаты или подписи.

  • Не дает такой же гранулярности, как подход, основанный на подписях.

  • При подключении базы данных к экземпляру SQL Server свойство TRUSTWORTHY в базе данных принимает значение OFF. Модули, которым доверяет владелец базы данных, не будут действительны до тех пор, пока администратор явно не задаст для свойства TRUSTWORTHY значение ON. Из этого неявно следует, что, для того чтобы подключенная база данных могла функционировать должным образом и обращаться к другим базам данных, предполагается некоторое вмешательство системного администратора.

Подход к установлению доверия с помощью подписей

Достоинства и недостатки этого подхода:

  • Обеспечивает гранулярный уровень доверия, но применяется только к контекстным переключениям внутри подписанных модулей.

  • Подпись нельзя применять к контекстным переключениям, которые устанавливаются отдельными инструкциями EXECUTE AS USER и EXECUTE AS LOGIN. Чтобы расширить область доверия с помощью этих инструкций, следует воспользоваться первым подходом, основанным на владельце базы данных.

  • Производители или разработчики приложений могут подписывать модули закрытым ключом, но перед поставкой модуля или базы данных закрытый ключ нужно удалить. Это работает, поскольку закрытые ключи используются только для подписи модулей. Для проверки подписей достаточно открытых ключей, связанных с модулями.

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