it-swarm.com.de

Wählen Sie Daten von einer anderen Datenbankinstanz auf demselben Server in SQL Server aus

Ich habe eine Abfrage unten gezeigt:

select count(*) as Count, datepart(yyyy, [LogDate]) as [Year]
from ViewAssociate..Auth_Log 
where ActionCode = 12
group by datepart(yyyy, [LogDate])
order by [Year]

Diese Abfrage ist Teil einer gespeicherten Prozedur, die auf der ReadAssociate-Datenbank basiert. Es wird versucht, Daten von ViewAssociate db abzurufen. Der Benutzer, der versucht, den gespeicherten Prozess auszuführen, hat keinen Zugriff auf die ViewAssociate-Datenbank, sodass die Abfrage einen Fehler auslöst.

Meine Frage ist, ob ich die Abfrage irgendwie ändern und ihr ein Benutzername-Passwort zum Ausführen geben kann, damit ich Daten von der ViewAssociate-Datenbank abrufen kann. Jemand schlug vor, Execute As aber das scheint nicht zu funktionieren.

execute as login = 'viewassociate' Ich erhalte diesen Fehler:

Kann nicht als Serverprinzipal ausgeführt werden, da das Prinzip "viewassociate" nicht vorhanden ist, dieser Prinzipaltyp nicht als Identitätswechsel angesehen werden kann oder Sie keine Berechtigung haben.

Diese Ansicht ist ein SQL-Login, das db_owner der ViewAssociate-Datenbank.

3
SP1

Wenn sich die Datenbank, zu der Sie eine Verbindung herstellen möchten, auf einer anderen Instanz befindet, würde ich empfehlen, einen Verbindungsserver einzurichten, mit dem Sie die Daten abrufen können. Auf diese Weise können Sie explizit Anmeldeinformationen verwenden, die für die Instanz vorhanden sind, zu der Sie eine Verbindung herstellen möchten. Außerdem können Sie Abfragen relativ einfach durchführen, indem Sie nur einen vierteiligen Namen verwenden müssen, um auf die Tabelle zu verweisen.

-- create a linked server
USE [master]  
GO  
EXEC master.dbo.sp_addlinkedserver   
     @server = '.\INSTANCE_NAME',   
     @srvproduct=N'SQL Server' ;  
GO  
-- add a login to the linked server
EXEC master.dbo.sp_addlinkedsrvlogin   
     @rmtsrvname = '.\INSTANCE_NAME',   
     @locallogin = NULL,   
     @useself = N'False',
     @rmtuser = 'user_name_from_other_instance',
     @rmtpassword = 'password_for_remote_user';  
GO 
-- now you can query the server
SELECT *
  FROM [.\INSTANCE_NAME].master.sys.databases;
GO

Für diese gespeicherten Prozeduren stehen weitere Optionen zur Verfügung. Sie können dieselbe Aktion auch mit SQL Server Management Studio ausführen. Ich habe einige Links zu der folgenden Dokumentation für Sie eingefügt:

Verbindungsserver

Verbindungsserver erstellen

sp_addlinkedserver

sp_addlinkedserverlogin

2
Mr.Brownstone

Dies ist eine einfache Sache, bei der Datenbanken aus Sicherheitsgründen standardmäßig von anderen Datenbanken isoliert sind. Vor SQL Server 2005 konnte dieses Problem durch Aktivieren der Funktion zur datenbankübergreifenden Verkettung behoben werden. Diese Option ist jedoch ziemlich weit offen, da keine Anpassung möglich ist, wer sie nutzen kann. Ab SQL Server 2005 wurde Module Signing eingeführt und bietet einen detaillierten Sicherheitsmechanismus zur Lösung dieses und vieler anderer Probleme.

Ich habe hier einige Beispiele (DBA.SE), die bereits zeigen, wie das geht, wie zum Beispiel:

Berechtigungen in Triggern bei Verwendung datenbankübergreifender Zertifikate

Da es sich um Trigger handelt, habe ich es für diese Frage vereinfacht, wie unten gezeigt:

[~ # ~] Bereinigung [~ # ~]

USE [master];
GO
IF EXISTS (SELECT 1 FROM [sys].[databases] WHERE [name] = N'DatabaseA')
BEGIN
    PRINT 'Dropping [DatabaseA] DB...';
    ALTER DATABASE [DatabaseA] SET OFFLINE WITH ROLLBACK IMMEDIATE;
    ALTER DATABASE [DatabaseA] SET ONLINE;
    DROP DATABASE [DatabaseA];
END;

IF EXISTS (SELECT 1 FROM [sys].[databases] WHERE [name] = N'DatabaseB')
BEGIN
    PRINT 'Dropping [DatabaseB] DB...';
    ALTER DATABASE [DatabaseB] SET OFFLINE WITH ROLLBACK IMMEDIATE;
    ALTER DATABASE [DatabaseB] SET ONLINE;
    DROP DATABASE [DatabaseB];
END;

IF (SUSER_ID(N'JohnnyLunchbucket') IS NOT NULL)
BEGIN
  PRINT 'Dropping [JohnnyLunchbucket] Login...';
  DROP LOGIN [JohnnyLunchbucket];
END;

[~ # ~] setup [~ # ~]

USE [master];

EXECUTE AS LOGIN = N'sa';
PRINT 'Creating databases...';
CREATE DATABASE [DatabaseA] COLLATE Latin1_General_100_CI_AS_SC;
CREATE DATABASE [DatabaseB] COLLATE Latin1_General_100_CI_AS_SC;
REVERT;
GO

-- Default for both options should be OFF, but just to be sure:
ALTER DATABASE [DatabaseA] SET DB_CHAINING OFF, TRUSTWORTHY OFF, RECOVERY SIMPLE;

ALTER DATABASE [DatabaseB] SET DB_CHAINING OFF, TRUSTWORTHY OFF, RECOVERY SIMPLE;
GO

CREATE LOGIN [JohnnyLunchbucket] WITH PASSWORD = 'OhSoSecure;)';


USE [DatabaseA];

CREATE USER [JohnnyLunchbucket] FOR LOGIN [JohnnyLunchbucket];
GO

CREATE PROCEDURE dbo.SelectFromDatabaseB
AS
SET NOCOUNT ON;

SELECT *
FROM   [DatabaseB].dbo.SomeTable;
GO

GRANT EXECUTE ON dbo.SelectFromDatabaseB TO [JohnnyLunchbucket];
GO

USE [DatabaseB];

CREATE TABLE dbo.SomeTable (Col1 INT);
INSERT INTO dbo.SomeTable ([Col1]) VALUES (111);
GO

TEST 1 (kein Zugriff)

USE [DatabaseA];

EXECUTE AS LOGIN = N'JohnnyLunchbucket';

SELECT * FROM [DatabaseB].dbo.SomeTable;
/*
Msg 916, Level 14, State 1, Line XXXXX
The server principal "JohnnyLunchbucket" is not able to access the database "DatabaseB" under the current security context.
*/

EXECUTE dbo.[SelectFromDatabaseB];
/*
Msg 916, Level 14, State 1, Procedure dbo.SelectFromDatabaseB, Line XXXXX [Batch Start Line YYYYY]
The server principal "JohnnyLunchbucket" is not able to access the database "DatabaseB" under the current security context.
*/

REVERT;

MODUL SIGNING HINZUFÜGEN

CREATE CERTIFICATE [PermissionsCert]
  AUTHORIZATION [dbo]
  ENCRYPTION BY PASSWORD = 'WeakPassword'
  WITH SUBJECT = 'Used to test granting permissions to code',
  EXPIRY_DATE = '2099-12-31';

ADD SIGNATURE TO [dbo].[SelectFromDatabaseB]
    BY CERTIFICATE [PermissionsCert]
    WITH PASSWORD = 'WeakPassword';

-- Copy Certificate (public key only) to DatabaseB
DECLARE @SQL NVARCHAR(MAX);
SET @SQL = N'USE  [DatabaseB];
CREATE CERTIFICATE [PermissionsCert] AUTHORIZATION [dbo] FROM BINARY = '
  + CONVERT(NVARCHAR(MAX), CERTENCODED(CERT_ID(N'PermissionsCert')), 1)
  + N';'

EXEC (@SQL);

USE [DatabaseB];

CREATE USER [PermissionsUser] FROM CERTIFICATE [PermissionsCert];

GRANT SELECT ON [dbo].[SomeTable] TO [PermissionsUser];
GO

TEST 2 (Zugriff gewährt, jedoch nur über signiertes Modul)

USE [DatabaseA];

EXECUTE AS LOGIN = N'JohnnyLunchbucket';

SELECT * FROM [DatabaseB].dbo.SomeTable;
/*
Msg 916, Level 14, State 1, Line XXXXX
The server principal "JohnnyLunchbucket" is not able to access the database "DatabaseB" under the current security context.
*/

EXECUTE dbo.[SelectFromDatabaseB];
-- 111

REVERT;

Nur den signierten Modulen wird der Zugriff auf die aus dem Zertifikat erstellten Anmeldungen und/oder Benutzer gewährt. Und Benutzer haben nur Zugriff auf die Module, auf die Sie ihnen Zugriff gewähren.

2
Solomon Rutzky