Nous avons deux bases de données, Adb
et Bdb
. Dans Bdb
, nous créons une vue qui référence une autre vue dans Adb
, comme ceci: CREATE VIEW Bdb.dbo.Bview AS SELECT * FROM Adb.dbo.Aview
.
Nous avons un Blogin
authentifié SQL, mappé sur Buser
, à la fois sur Adb
et Bdb
, avec au moins le db_datareader
rôle sur les deux.
Ce qui suit ne fonctionne pas:
USE Bdb;
EXECUTE AS USER = 'Buser';
SELECT * FROM Bdb.dbo.Bview;
SELECT * FROM Adb.dbo.Aview;
L'erreur suivante est générée pour les deux sélections:
Msg 916, Level 14, State 1, Line 4
The server principal "Buser" is not able to access the database "Adb" under the current security context.
Cependant, cela fonctionne:
USE Adb;
EXECUTE AS USER = 'Buser';
SELECT * FROM Adb.dbo.Aview;
SELECT * FROM Bdb.dbo.Bview;
J'ai remarqué que la première fois que je USE Bdb
et passer à Buser
, je ne vois aucune autre base de données:
USE Bdb;
EXECUTE AS USER = 'Buser';
SELECT * FROM sys.databases; -- only master, tempdb and Bdb is shown
Mais quand je USE Adb
d'abord, je les vois tous, même ceux qui n'ont pas le Buser
et qui ne sont pas accessibles par celui-ci:
USE Adb;
EXECUTE AS USER = 'Buser';
SELECT * FROM sys.databases; -- all DBs on the server are shown
Quelle pourrait être la cause de ce problème? Que dois-je vérifier?
Tout d'abord: NE PAS ACTIVER LA CONFIANCE !! Il n'y a absolument aucune raison d'ouvrir un trou de sécurité aussi important. (note: msdb
a TRUSTWORTHY
activé et c'est très bien car c'est une base de données fournie par Microsoft; les bases de données créées par l'utilisateur ne sont jamais besoinTRUSTWORTHY
activée)
Maintenant, si cela fonctionne lors de l'emprunt d'identité d'un utilisateur au lieu d'une connexion, cela est dû à votre [Adb]
La base de données est déjà activée en tant que TRUSTWORTHY ON
, qui supprime la quarantaine par défaut qui existe lors de l'utilisation de l'emprunt d'identité au niveau de la base de données. Vous pouvez le voir en exécutant ce qui suit:
SELECT db.is_trustworthy_on, *
FROM sys.databases db
WHERE db.[name] IN (N'Adb', N'Bdb');
En supposant que c'est le cas que Adb
est activé pour TRUSTWORTHY
et Bdb
ne l'est pas, alors veuillez ne pas activer TRUSTWORTHY
pour Bdb
. Il serait préférable de désactiverTRUSTWORTHY
pour Adb
et d'utiliser la signature de module pour y parvenir:
ALTER DATABASE [Adb] SET TRUSTWORTHY OFF;
Pour un exemple de cet accès inter-base de données via la signature de module, veuillez consulter la réponse suivante (ici sur DBA.SE):
Pour plus d'informations sur les raisons pour lesquelles vous devriez utiliser la signature de module au lieu de TRUSTWORTHY (ou même le chaînage de propriété entre bases de données), veuillez consulter le message suivant:
Pour plus d'informations sur la signature de module en général, veuillez consulter:
Comme @Nic l'a mentionné dans un commentaire sur la question, il est préférable d'utiliser EXECUTE AS LOGIN
au lieu de EXECUTE AS USER
lors des tests. Les connexions sont au niveau du serveur et auront accès aux bases de données dans lesquelles un utilisateur a été créé pour cette connexion. Ce sera comme se connecter à SQL Server en tant que compte.
La raison de la différence est indiquée dans la page de documentation Microsoft pour Extension de l'emprunt d'identité de base de données en utilisant EXECUTE AS
Comprendre la portée de l'emprunt d'identité
...
Toutefois, lors de l'emprunt d'identité d'un principal à l'aide de l'instruction EXECUTE AS USER, ou dans un module de portée de base de données à l'aide de la clause EXECUTE AS, la portée de l'emprunt d'identité est limitée à la base de données par défaut. Cela signifie que les références à des objets hors de la portée de la base de données renverront une erreur.
En outre, il existe de nombreuses bonnes informations sur la page MSDN "Extension de l'emprunt d'identité de base de données en utilisant EXECUTE AS" (liée ci-dessus) qui explique les authentificateurs et le raisonnement derrière ces règles.
Étant donné que ces deux bases de données sont fournies par le fournisseur (des informations ont été ajoutées après avoir soumis cette réponse), il est probablement préférable de passer simplement à EXECUTE AS LOGIN
et pas apportez des modifications aux bases de données (pour la signature de module).
Bdb est-il une base de données fiable?
SELECT name, is_trustworthy_on FROM sys.databases
Pour utiliser EXECUTE AS sur une autre base de données, vous devez configurer la confiance entre les bases de données:
ALTER DATABASE Bdb SET TRUSTWORTHY ON;
GO
Cependant, il y a beaucoup de problèmes de sécurité autour de cela, ne le faites que si vous comprenez réellement les risques.
Vous pouvez en savoir plus ici: https://technet.Microsoft.com/en-us/library/ms188304 (v = sql.105) .aspxhttps://support.Microsoft .com/en-us/help/2183687/guidelines-for-using-the-trustworthy-database-setting-in-sql-server