Estendendo representação de banco de dados com EXECUTE AS

O SQL Server permite representar outra entidade usando explicitamente a instrução EXECUTE AS autônoma ou usando implicitamente a cláusula EXECUTE AS nos módulos. A instrução EXECUTE AS autônoma pode ser usada para representar entidades de nível de servidor ou logons usando a instrução EXECUTE AS LOGIN. A instrução EXECUTE AS autônoma também pode ser usada para representar entidades de nível de banco de dados ou usuários usando a instrução EXECUTE AS USER.

As representações implícitas executadas através da cláusula EXECUTE AS nos módulos representam o usuário ou logon especificado no nível de servidor ou banco de dados. Esta representação depende do tipo do módulo, um módulo de nível de banco de dados, como um procedimento armazenado ou função, ou um módulo de nível de servidor, como um gatilho de nível de servidor.

Entendendo o escopo da representação

Ao representar uma entidade usando a instrução EXECUTE AS LOGIN ou em um módulo com escopo no servidor usando a cláusula EXECUTE AS, o escopo da representação é para todo o servidor. Isso significa que depois da alternância de contexto, todo recurso no servidor no qual o logon representado tem permissões pode ser acessado.

No entanto, ao representar uma entidade usando a instrução EXECUTE AS USER ou em um módulo com escopo no banco de dados usando a cláusula EXECUTE AS, o escopo da representação é restrito ao banco de dados, por padrão. Isso significa que referências a objetos fora do escopo do banco de dados retornarão um erro. Para entender a razão deste comportamento padrão, considere o cenário a seguir.

É possível que o proprietário de um banco de dados, enquanto tiver permissões completas nesse banco de dados, não tenha permissões fora do escopo do banco de dados. Dessa forma, o SQL Server não permite que o proprietário do banco de dados faça uma representação ou permita que outra pessoa o faça, outro usuário, para acessar recursos além do escopo das permissões atuais do proprietário do banco de dados.

Por exemplo, considere dois bancos de dados em um ambiente de hospedagem, sendo que cada um deles pertence a uma entidade proprietária separada. O banco de dados1 pertence a Bob e o banco de dados2 pertence a Fred. Nem Bob nem Fred desejam que outra pessoa acesse recursos em seus respectivos bancos de dados. Como proprietário do banco de dados1, Bob pode criar um usuário para Fred em seu banco de dados e, como ele tem permissão total no banco de dados 1, também pode representar o usuário Fred. Porém, por causa das restrições de segurança impostas pelo SQL Server, Bob não pode acessar o banco de dados de Fred no contexto representado. Sem estas restrições padrão, Bob poderia acessar os dados de Fred sem o conhecimento dele. É por isso que o escopo das representações de nível de banco de dados é associado por padrão ao banco de dados.

Porém, em determinados cenários pode ser útil estender o escopo da representação seletivamente para além do banco de dados. Por exemplo, no caso de um aplicativo que usa dois bancos de dados e requer acesso a um banco de dados do outro banco de dados.

Considere o caso de um aplicativo de marketing que chama um procedimento armazenado denominado GetSalesProjections no banco de dados Marketing e o procedimento armazenado tem uma alternância de contexto de execução nele. O procedimento armazenado faz a chamada no banco de dados Vendas para recuperar informações de vendas da tabela SalesStats. Por padrão, este cenário não funcionará porque um contexto de execução estabelecido dentro de um banco de dados não é válido fora dele. No entanto, os desenvolvedores do aplicativo de marketing não desejam que os usuários do aplicativo de marketing tenham acesso direto ao banco de dados Vendas ou tenham permissões em qualquer objeto dentro dele. A solução ideal seria usar a cláusula EXECUTE AS no procedimento armazenado para representar um usuário que tenha as permissões necessárias no banco de dados Vendas. Porém, as restrições padrão atualmente estabelecidas impedem isso. Então como os desenvolvedores podem solucionar este problema?

No SQL Server, você pode estender seletivamente o escopo da representação de banco de dados estabelecido em um banco de dados criando um modelo confiável entre dois bancos de dados. Mas, antes de descrever esse modelo confiável e como o escopo da representação pode ser seletivamente estendido, você deve entender a autenticação e a função dos autenticadores no SQL Server.

Entendendo autenticadores

A autenticação é o processo pelo qual uma entidade específica estabelece e prova sua identidade em um sistema. Um autenticador é uma entidade que autentica ou atesta a autenticidade de uma determinada entidade. Por exemplo, quando uma conexão é feita com o SQL Server, o logon que é estabelecido para essa conexão é autenticado pela instância do SQL Server.

Considere o caso em que um usuário alterna explicitamente o contexto no nível de servidor usando a instrução EXECUTE AS LOGIN. Isso requer permissões de representação no nível de servidor. Essas permissões permitem ao usuário autorizado da permissão, o chamador da instrução EXECUTE AS LOGIN, a capacidade de representar o logon especificado em qualquer local da instância do SQL Server. Ou seja, a instrução permite que o chamador simule o ato de efetuar logon como esse logon representado. O proprietário do escopo de nível de servidor das permissões é o sysadmin que possui a instância do SQL Server. Nesse caso de representação de nível de servidor, o autenticador é o sysadmin ou a própria instância do SQL Server.

No entanto, considere o caso no qual o contexto é estabelecido devido a uma instrução EXECUTE AS USER ou uma cláusula EXECUTE AS em um módulo com escopo no banco de dados. Nesses casos, as permissões de representação dentro do escopo do banco de dados são verificadas. O padrão para o escopo das permissões de REPRESENTAÇÃO em usuários é o próprio banco de dados, o proprietário do dbo. O autenticador dessas representações também é o proprietário do banco de dados. Além disso, é o proprietário do banco de dados que efetivamente estabelece a identidade do usuário representado e atesta sua autenticidade. Como o proprietário do banco de dados possui o banco de dados completo, o contexto representado é considerado autêntico em todos os locais desse banco de dados específico. Porém, fora desse banco de dados, o contexto representado não é válido.

Como os autenticadores são usados

Os autenticadores são usados para determinar se um contexto estabelecido é válido dentro de um determinado escopo. Freqüentemente, o autenticador é o administrador de sistema (SA) ou a instância do SQL Server ou, dentro dos bancos de dados, o dbo. O autenticador é efetivamente o proprietário do escopo dentro do qual o contexto para um determinado usuário ou logon é estabelecido. Estas informações do autenticador são capturadas das informações de token mantidas para o logon e para o usuário e são visíveis através das exibições sys.user_token e sys.login_token. Para obter mais informações, consulte Compreendendo o contexto de execução.

ObservaçãoObservação

Se nenhuma informação de autenticador for retornada na exibição do token, o autenticador será a instância do SQL Server. Isso ocorre quando não há alternância de contexto ou quando a representação está no nível de servidor.

Um contexto de execução que tem o proprietário de um escopo como seu autenticador é válido através desse escopo. Isso ocorre porque o proprietário de um escopo, por exemplo, um banco de dados, é implicitamente confiável em todas as entidades dentro do escopo. O contexto também é válido em outros escopos, por exemplo, outros bancos de dados ou a própria instância do SQL Server, na qual o autenticador é confiável. Assim, a validade do contexto do usuário representado fora do escopo do banco de dados depende de o autenticador de contexto ser ou não confiável dentro do escopo de destino. Essa confiança é estabelecida concedendo a permissão AUTHENTICATE ao autenticador se o escopo de destino for outro banco de dados, ou AUTHENTICATE SERVER se o escopo de destino for uma instância do SQL Server.

Estendendo o escopo da representação

Para estender o escopo de uma representação dentro de um banco de dados para um escopo de destino, como outro banco de dados ou instância do SQL Server, as seguintes condições devem ser atendidas.

  • O autenticador deve ser confiável no escopo de destino.

  • O banco de dados de origem deve ser marcado como confiável.

Confiando no autenticador

Usando o exemplo anterior dos bancos de dados Vendas e Marketing, a ilustração a seguir mostra o procedimento armazenado GetSalesProjections no banco de dados Marketing que acessa os dados na tabela SalesStats do banco de dados Vendas. O procedimento armazenado contém a cláusula EXECUTE AS USER MarketingExec. O proprietário do banco de dados Vendas é SalesDBO e o proprietário do banco de dados Marketing é MarketingDBO.

EXECUTE AS alterna o contexto de execução de um módulo

Quando o procedimento armazenado GetSalesProjections é chamado por um usuário, a cláusula EXECUTE AS alterna implicitamente o contexto de execução do procedimento armazenado do usuário que chama para o usuário MarketingExec. O autenticador desse contexto é MarketingDBO, o proprietário do banco de dados Marketing. Por padrão, esse procedimento pode acessar qualquer recurso do banco de dados Marketing que o usuário MarketingExec tem permissão para acessar. No entanto, para acessar uma tabela no banco de dados Vendas, o banco de dados Vendas deve confiar no autenticador MarketingDBO.

Você pode fazer isso criando um usuário denominado MarketingDBO no banco de dados Vendas, que seja mapeado para o logon do MarketingDBO, e, em seguida, concedendo a esse usuário a permissão AUTHENTICATE no banco de dados Vendas. Como resultado, qualquer contexto de execução que possua o usuário autorizado dessa permissão como seu autenticador será válido dentro do banco de dados. Como o autenticador MarketingDBOtem permissão AUTHENTICATE no banco de dados Vendas, o contexto para o usuário MarketingExec estabelecido pela cláusula EXECUTE AS no procedimento armazenado GetSalesProjections no banco de dados Marketing é confiável no banco de dados Vendas.

Apesar de esse exemplo demonstrar como estender o escopo da representação para permitir o acesso a um objeto em um banco de dados externo, também é possível estender o escopo da representação para a instância do SQL Server. Por exemplo, se o procedimento fosse criar um logon, que é uma ação de nível de servidor que requer uma permissão em todo servidor, a permissão AUTHENTICATE SERVER teria de ser concedida para o autenticador do contexto. Isso significa que todo contexto que possua o usuário autorizado da permissão AUTHENTICATE SERVER como seu autenticador é confiável em toda a instância do SQL Server**,**, como se o contexto estivesse efetuando log diretamente na instância do SQL Server.

Confiando no banco de dados

No SQL Server, o modelo confiável avança um pouco mais para fornecer segurança adicional e granularidade para estender o escopo da representação de nível de banco de dados. Você pode usar a permissão AUTHENTICATE para que o escopo de destino confie no autenticador de um contexto, mas também pode determinar se a instância do SQL Server confiará no banco de dados de origem e em seu conteúdo.

Para ilustrar isso, suponha que a entidade MarketingDBO possua outro banco de dados chamado Conferência. Suponha também que MarketingDBO deseja que os contextos de execução especificados no banco de dados Marketing tenham acesso aos recursos no banco de dados Vendas. No entanto, essa entidade não quer que nenhum contexto estabelecido no banco de dados Conferência tenha acesso ao banco de dados Vendas.

Para isso, o banco de dados que contém o módulo no qual um contexto de representação é usado para acessar recursos fora do banco de dados deve ser marcado como confiável. A propriedade TRUSTWORTHY indica se a instância do SQL Server confia no banco de dados e em seu conteúdo . A propriedade TRUSTWORTHY tem dois propósitos:

  1. Reduzir a ameaça dos bancos de dados que estão anexados à instância do SQL Server e que podem conter módulos maliciosos definidos para execução no contexto de um usuário com muitos privilégios.

    Isso é feito certificando-se de que os bancos de dados anexados não estejam marcados como confiáveis por padrão. Ou certificando-se de que o acesso a recursos fora do banco de dados através de módulos potencialmente maliciosos requer que o banco de dados seja marcado como confiável. A definição da propriedade TRUSTWORTHY em um banco de dados é restrita a membros da função de servidor fixa sysadmin.

  2. Permitir que o administrador da instância do SQL Server distinga entre os bancos de dados que devem ou não ter permissão para acessar recursos externos quando esses bancos de dados têm o mesmo proprietário e esse proprietário é confiado como um administrador em algum escopo.

Esse comportamento pode ser controlado usando a propriedade TRUSTWORTHY. Por exemplo, suponha que você tenha uma situação na qual os contextos representados de um banco de dados, o banco de dados 1, devem ser confiáveis, enquanto que os contextos de outro banco de dados, o banco de dados 2, não devem ser confiáveis, e ambos possuem o mesmo proprietário confiado como autenticador do escopo de destino. A propriedade TRUSTWORTHY pode ser configurada como ON para o banco de dados1 e como OFF para o banco de dados2 para se certificar de que os módulos no banco de dados 2 não possam acessar recursos fora desse banco de dados.

A ilustração a seguir mostra o uso da propriedade de banco de dados TRUSTWORTHY para controlar o acesso a recursos fora do escopo do banco de dados de origem. MarketingDBO tem as permissões AUTHENTICATE no banco de dados Vendas e é o proprietário dos bancos de dados Marketing e Conferência. O procedimento armazenado GetSalesProjections no banco de dados Marketing pode acessar com êxito o banco de dados Vendas porque atende aos dois requisitos de segurança: o autenticador, MarketingDBO, é confiável no escopo de destino e o banco de dados de origem, Marketing, é confiável. As tentativas de acesso ao banco de dados Vendas do banco de dados Conferência são negadas porque somente um requisito é atendido: o autenticador, MarketingDBO, é confiável no escopo de destino.

Controlando o acesso de banco de dados aos recursos externos

Sempre que for feita uma tentativa de acessar um recurso fora do escopo do banco de dados usando um contexto representado, a instância do SQL Server verificará se o banco de dados do qual a solicitação foi originada e se o autenticador são confiáveis.

Certificados e chaves assimétricas como autenticadores

Um contexto de representação estabelecido em um banco de dados pode ser estendido para acessar recursos fora do escopo do banco de dados usando o proprietário do banco de dados como um autenticador. Isso exige que o proprietário do banco de dados seja confiável no recurso externo e que o próprio banco de dados também o seja. No entanto, essa abordagem significa que quando um proprietário do banco de dados confiável tem as permissões AUTHENTICATE ou AUTHENTICATE SERVER no escopo de destino e o banco de dados de chamada é confiável, qualquer contexto representado estabelecido será válido no escopo de destino que confia no proprietário do banco de dados.

Um nível mais granular de confiança pode ser necessário. Suponha que o requisito comercial indique confiança apenas em alguns módulos no banco de dados de origem que usa a cláusula EXECUTE AS para acessar o recurso de destino, mas não confie em todo o banco de dados de origem. Por exemplo, suponha que SalesDBO queira se certificar de que apenas o procedimento armazenado GetSalesProjections possa acessar a tabela SalesStats como o usuário MarketingExec, mas não deseja que qualquer pessoa no banco de dados Marketing com permissões de representação em MarketingExec possa acessar recursos no banco de dados Vendas. Confiar em MarketingDBO e definir o banco de dados Marketing como confiável não cumprirá essa tarefa. Para fornecer um nível adicional de granularidade para atender a esse requisito, o modelo confiável permitirá que certificados ou chaves assimétricas sejam usados como autenticadores. Ele se beneficia de uma técnica chamada assinatura. Para obter mais informações sobre assinatura, consulte ADD SIGNATURE (Transact-SQL).

Usando assinaturas

As assinaturas em um módulo verificam se o código dentro de um módulo só pode ser modificado por uma pessoa com acesso à chave particular usada para assinar o módulo. Considerando as garantias do processo de assinatura, você pode confiar no certificado ou na chave assimétrica especificada na assinatura. Mais especificamente, você pode confiar no proprietário do certificado ou na chave assimétrica, e não apenas no proprietário do banco de dados.

A confiança no módulo assinado é realizada concedendo a permissão AUTHENTICATE ou AUTHENTICATE SERVER para o usuário no escopo de destino mapeado para o certificado ou para a chave assimétrica.

Com essa abordagem, um contexto de execução estabelecido dentro de um módulo assinado usando um certificado confiável é válido no escopo de destino no qual o certificado é confiável.

Por exemplo, suponha que o procedimento GetSalesProjections seja assinado usando um certificado chamado C1. O certificado C1 deve existir no banco de dados Vendas e um usuário, por exemplo, CertUser1, deve ser mapeado para o certificado C1. Concede-se então as permissões AUTHENTICATE a CertUser1 no banco de dados Vendas.

Quando o procedimento é chamado, sua assinatura é verificada para garantir que ela não tenha sido violada durante a assinatura. Se a assinatura for verificada, o contexto estabelecido pela cláusula EXECUTE AS no módulo terá o certificado C1 como seu autenticador. Se a assinatura não for verificada, o autenticador não será adicionado ao token e a tentativa de acesso ao recurso externo falhará.

A ilustração a seguir mostra o uso de um módulo assinado para controlar o acesso a recursos fora do escopo do banco de dados de origem. O procedimento GetSalesProjections no banco de dados Marketing é assinado usando um certificado chamado C1. O certificado C1 está presente no banco de dados Vendas e o usuário CertUser é mapeado para o certificado. CertUser1 tem as permissões AUTHENTICATE no banco de dados Vendas.

Certificado usado para restringir o acesso ao banco de dados

A confiança nesse autenticador é verificada da mesma forma que é verificada quando o proprietário do banco de dados é o autenticador. Ou seja, ela é verificada consultando a permissão AUTHENTICATE SERVER ou AUTHENTICATE. No entanto, como a confiança é estabelecida em um nível granular e o módulo não pode ser alterado sem modificar a assinatura, não há necessidade de verificar a propriedade TRUSTWORTHY no banco de dados.

Isso reduz a ameaça que vem de bancos de dados com código malicioso que estão anexados. O invasor teria que assinar o módulo com a chave particular que correspondesse ao certificado que já é confiável. Porém, o invasor não teria acesso a esta chave. Além disso, se um módulo confiável já existente fosse modificado ou um novo módulo fosse criado, esse módulo não teria uma assinatura confiável válida.

Para obter mais informações, consulte Assinatura de módulo (Mecanismo de Banco de Dados).

Regras para estender o escopo de representação do banco de dados

Resumindo, o escopo de uma representação de um contexto estabelecido em um banco de dados pode ser estendido para outros escopos se, e apenas se:

  • O autenticador, o proprietário do banco de dados ou um certificado ou chave assimétrica usada para assinar o módulo, deve ser confiável no escopo de destino. Isso pode ser feito concedendo as permissões AUTHENTICATE ou AUTHENTICATE SERVER para a entidade mapeada para o proprietário do banco de dados, para o certificado ou para a chave assimétrica.

  • Se o autenticador for o proprietário do banco de dados, o banco de dados de origem deverá ser marcado como confiável. Você pode fazer isso definindo a propriedade TRUSTWORTHY como ON para o banco de dados.

Selecionando o mecanismo de confiança que atenda às suas necessidades

Há vantagens e desvantagens na abordagem do proprietário do banco de dados e da assinatura. O mecanismo mais adequado para você depende de seus requisitos comerciais e de seu ambiente de negócios.

Abordagem do proprietário do banco de dados

A abordagem do proprietário do banco de dados para estabelecer confiança tem as seguintes vantagens e desvantagens:

  • Não requer nenhum conhecimento de conceitos de criptografia como certificados ou assinaturas.

  • Não fornece tanta granularidade quanto a abordagem baseada em assinatura.

  • Anexar um banco de dados com uma instância do SQL Server definirá a propriedade TRUSTWORTHY no banco de dados como OFF. Os módulos confiáveis pelo proprietário do banco de dados não serão válidos até que o administrador do sistema defina explicitamente a propriedade TRUSTWORTHY como ON. Isso implica na possível intervenção do administrador do sistema, antes de o banco de dados anexado poder funcionar da forma que você deseja e acessar outros bancos de dados.

Abordagem de assinatura

A abordagem de assinatura para estabelecer confiança tem as seguintes vantagens e desvantagens:

  • Pode fornecer um nível granular de confiança, mas isso se aplica apenas às alternâncias de contextos efetuadas dentro dos módulos assinados.

  • A assinatura não pode ser aplicada às alternâncias de contextos estabelecidas através das instruções autônomas EXECUTE AS USER e EXECUTE AS LOGIN. Essas instruções exigem a abordagem baseada no proprietário do banco de dados para estender o escopo de confiança.

  • O fornecedor ou desenvolvedor do aplicativo pode assinar o módulo com uma chave particular, mas ela deve ser removida antes que os módulos ou o banco de dados sejam enviados. Isso funciona porque as chaves particulares só são usadas para assinar os módulos. Para verificação de assinatura, as chaves públicas associadas ao módulo são suficientes.

  • Anexar um banco de dados não terá efeito nos módulos que são confiáveis devido às suas assinaturas. Funcionarão sem requisitos adicionais.