web-dev-qa-db-fra.com

Vue entre bases de données - Impossible d'accéder à la base de données dans le contexte de sécurité actuel

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?

3
ROAL

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):

Vue d'accès basée sur la table dans une autre base de données sans compte dans cette autre base de données

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:

S'IL VOUS PLAÎT, s'il vous plaît, veuillez cesser d'utiliser l'emprunt d'identité, la confiance et le chaînage de propriété croisée

Pour plus d'informations sur la signature de module en général, veuillez consulter:

https://ModuleSigning.info/


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).

6
Solomon Rutzky

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

0
JasonBluefire