eu tenho essa configuração
- Criei dois bancos de dados (origem e destino).
- O banco de dados de origem possui um procedimento armazenado que está acessando a tabela no banco de dados de destino.
- O procedimento armazenado é executado como conta de serviço
- O login da conta de serviço tem conta de usuário em ambos os bancos de dados
- A conta de serviço tem permissão de conexão e autenticação ao banco de dados de destino
- A conta de serviço tem permissão de leitura no esquema de banco de dados de destino
- Ambos os bancos de dados têm confiança em
mesmo assim deu erro
O principal do servidor "ServiceAccount" não pode acessar o banco de dados "TargetDatabase" no contexto de segurança atual.
script SQL
-- Create logins
CREATE LOGIN SourceDatabaseOwner WITH PASSWORD = 'Pa$$w0rd'
CREATE LOGIN TargetDatabaseOwner WITH PASSWORD = 'Pa$$w0rd'
CREATE LOGIN ServiceAccount WITH PASSWORD = 'Pa$$w0rd'
-- Create databases
CREATE DATABASE SourceDatabase
CREATE DATABASE TargetDatabase
-- Setup trustworthy
ALTER DATABASE SourceDatabase SET TRUSTWORTHY ON;
ALTER DATABASE TargetDatabase SET TRUSTWORTHY ON;
-- Setup database owners
USE SourceDatabase
GO
EXEC dbo.sp_changedbowner @loginame = N'SourceDatabaseOwner'
USE TargetDatabase
GO
EXEC dbo.sp_changedbowner @loginame = N'TargetDatabaseOwner'
-- Add ServiceAccount to source database
USE SourceDatabase
GO
CREATE USER ServiceAccount FOR LOGIN ServiceAccount;
-- Add ServiceAccount to target database
USE TargetDatabase
GO
CREATE USER ServiceAccount FOR LOGIN ServiceAccount;
-- Enable ServiceAccount to authenticate to target database
USE TargetDatabase
GO
GRANT AUTHENTICATE TO ServiceAccount;
-- Grant permissions
USE TargetDatabase
GO
GRANT SELECT ON SCHEMA::dbo TO ServiceAccount
-- Create table with data
USE TargetDatabase
GO
create table dbo.InterestingData (Id int identity primary key, Content nvarchar(255))
insert into dbo.InterestingData (Content) values ('Foo'), ('Bar')
-- Create stored procedure executing under service account and accessing target database
USE SourceDatabase
GO
create or alter procedure dbo.GetData
with execute as 'ServiceAccount' as
begin
select id, content from TargetDatabase.dbo.InterestingData
end
-- Execution does not work under service account
-- The server principal "ServiceAccount" is not able to access the database "TargetDatabase" under the current security context.
exec dbo.GetData
Então continuei e tentei assinar o procedimento com o certificado e configurar permissões na tabela de destino para o login desse certificado
-- create certificate in master
use master
go
CREATE CERTIFICATE SignProcedureCert
ENCRYPTION BY PASSWORD = 'Pa$$w0rd'
WITH SUBJECT = 'Certificate for signing stored procedures'
GO
-- backup certificate
BACKUP CERTIFICATE SignProcedureCert TO FILE ='C:\Certs\SignProcedureCert.cer'
WITH PRIVATE KEY
(
FILE = 'C:\Certs\SignProcedureCert.pvk',
DECRYPTION BY PASSWORD = 'Pa$$w0rd',
ENCRYPTION BY PASSWORD = 'Pa$$w0rd'
)
GO
-- create login from the certificate
create login SignProcedureLogin from certificate SignProcedureCert
-- Import certificate to the source database
CREATE CERTIFICATE SignProcedureCert
FROM FILE = 'C:\Certs\SignProcedureCert.cer'
WITH PRIVATE KEY (FILE = 'C:\Certs\SignProcedureCert.pvk',
ENCRYPTION BY PASSWORD = 'Pa$$w0rd',
DECRYPTION BY PASSWORD = 'Pa$$w0rd')
-- Sign the procedure
ADD SIGNATURE TO dbo.GetData
BY CERTIFICATE SignProcedureCert
WITH PASSWORD = 'Pa$$w0rd';
GO
-- Setup permission for SignProcedureLogin to target database
USE TargetDatabase
GO
CREATE USER SignProcedureLogin FOR LOGIN SignProcedureLogin;
GRANT SELECT ON SCHEMA::dbo TO SignProcedureLogin
então agora eu deveria ter essa configuração
mas quando eu executo
USE SourceDatabase
GO
exec dbo.GetData
eu tenho o mesmo erro
O principal do servidor "ServiceAccount" não pode acessar o banco de dados "TargetDatabase" no contexto de segurança atual.
o que estou perdendo?
Atualizar
Quando eu removo a with execute as
cláusula, ela funciona
-- Setup trustworthy
ALTER DATABASE SourceDatabase SET TRUSTWORTHY OFF;
ALTER DATABASE TargetDatabase SET TRUSTWORTHY OFF;
USE SourceDatabase
GO
create or alter procedure dbo.GetData
--with execute as 'ServiceAccount'
as
begin
select id, content from TargetDatabase.dbo.InterestingData
end
GRANT EXECUTE ON SCHEMA::dbo TO ServiceAccount
execute as login = 'ServiceAccount'
exec dbo.GetData
revert
mas ainda é possível executar de alguma forma o procedimento com a with execute as
cláusula?