2012-06-18 10 views
5

Versione breve: Posso concedere l'accesso a database esterni a un ruolo?Concessione dell'accesso a un db agli utenti/ruoli di un altro

Versione lunga:

Sto lavorando su report utilizzando Crystal, che sta recuperando dati da un'istanza di SQL Server applicazioni (database1).

L'applicazione sta eseguendo i report e sovrascrive la connessione nel report, non ho accesso al codice delle applicazioni.

Ho aggiunto un nuovo DB al server (database2) che raccoglie informazioni da una centrale telefonica e desidero unire alcune di queste informazioni ai dati delle applicazioni (database1).

È possibile unire i dati e i report funzionano quando vengono eseguiti all'interno del progettista (con accesso come SA) ma quando i report vengono eseguiti esternamente attraverso l'applicazione, falliscono con un errore abbastanza generico (Impossibile recuperare i dati).

Suppongo che l'errore sia causato dalle nuove autorizzazioni DB come se eseguissi il login nell'applicazione come SA l'errore scompare.

L'applicazione dispone di un ruolo DB speciale per gli utenti che eseguono rapporti, quando si aggiunge una tabella/vista/sp all'applicazione db (database1) Posso semplicemente assegnare select/execute a questo ruolo per consentire ai report di accedere all'oggetto .

Ora ho un oggetto in un diverso db, tuttavia il ruolo non è facilmente accessibile.

Esiste un modo per fare riferimento al secondo db (database2) tramite il ruolo esistente?

esempio:

USE [database1] 
GRANT EXECUTE ON [database2].[dbo].[CUSTOM_PROCEDURE] TO [applicationrole1] 

OR 

USE [database2] 
GRANT EXECUTE ON [dbo].[CUSTOM_PROCEDURE] TO [database1].[dbo].[applicationrole1] 

Idealmente Voglio essere in grado di collegare al ruolo in qualche modo piuttosto che ri-creazione di un nuovo ruolo come il ruolo viene aggiornato con l'applicazione regolarmente quando vengono aggiunti nuovi utenti/configurati.

(non registrata con Crystal Reports-in quanto questo non è correlato al problema)

Edit:

Esiste un modo per fare qualcosa di simile:

INSERT INTO Database2.sys.database_principals 
SELECT * FROM Database1.sys.database_principals 
WHERE [type] = 'S' 

Per copiare gli utenti (non i login) e quindi aggiungere i membri del ruolo?

risposta

3

Presumibilmente, si utilizzerà un accesso che ha accesso a entrambi i database (come nel caso di SA). Dovresti creare il ruolo appropriato e assegnare i diritti a ciascun database, quindi creare l'utente (collegato al login che stai utilizzando) in entrambi, aggiungendo ciascuno al ruolo che hai creato.

Il T-SQL sarà simile a questo:

use master 
go 
create login testuser with password = 'mypassword123' 
go 

use test 
go 

create role reporting 
grant select on something to reporting -- grant your permissions here 

create user testuser for login testuser 
exec sp_addrolemember 'reporting', 'testuser' 
go 

use test2 
go 

create role reporting 
grant select on something2 to reporting -- grant your permissions here 

create user testuser for login testuser 
exec sp_addrolemember 'reporting', 'testuser' 
go 

Ora posso collegarsi a test ed eseguire

select * from something 
select * from test2.dbo.something2 

Naturalmente, devi modificare le borse di studio da eseguire sul desiderato stored procedure, ma sembra che tu abbia già capito.

Dopodiché, si tratta semplicemente di eseguire un semplice script per creare login, utenti e aggiungerli al ruolo. login

declare @sql nvarchar(max), @username nvarchar(50), @password nvarchar(50) 

-- ########## SET PARAMETERS HERE 
SET @username = N'testguy' 
SET @password = N'test123' 
-- ########## END SET PARAMETERS 

set @sql = N'USE master; CREATE LOGIN [' + @username + N'] WITH PASSWORD = N''' + @password + N'''; USE database1; CREATE USER [' + @username + N'] FOR LOGIN [' + @username + N']; EXEC sp_addrolemember ''reporting'', ''' + @username + N'''; USE database2; CREATE USER [' + @username + N'] FOR LOGIN [' + @username + N']; EXEC sp_addrolemember ''reporting'', ''' + @username + N''';' 
exec sp_executesql @sql 

sincronizzazione, gli utenti e ruoli automaticamente

Questo script troverà tutti gli account di accesso di SQL (è possibile modificare questo a tutto ciò ha un senso per voi, le finestre e gli account di SQL, i conti che contengono una certa stringa, qualunque cosa), assicurarsi che l'utente sia stato creato in database1 e database2 e si assicuri che vengano entrambi aggiunti al ruolo reporting. È necessario assicurarsi che il ruolo reporting sia creato su entrambi i database, ma è necessario farlo una sola volta.

Successivamente, è possibile eseguire questo script periodicamente, manualmente o utilizzando un processo di Agente SQL. Tutto ciò che devi fare è creare il login per il server; quando lo script viene eseguito, farà il resto.

declare @login nvarchar(50), @user1 nvarchar(50), @user2 nvarchar(50), @sql nvarchar(max), @rolename nvarchar(50) 

SET @rolename = 'reporting' 

declare c cursor for 
select sp.name as login, dp1.name as user1, dp2.name as user2 from sys.server_principals as sp 
    left outer join database1.sys.database_principals as dp1 on sp.sid = dp1.sid 
    left outer join database2.sys.database_principals as dp2 on sp.sid = dp2.sid 
where sp.type = 'S' 
    and sp.is_disabled = 0 

open c 

fetch next from c into @login, @user1, @user2 

while @@FETCH_STATUS = 0 begin 

    -- create user in db1 
    if (@user1 is null) begin 
     SET @sql = N'USE database1; CREATE USER [' + @login + N'] FOR LOGIN [' + @login + N'];' 
     EXEC sp_executesql @sql 
    end 

    -- ensure user is member of role in db1 
    SET @sql = N'USE database1; EXEC sp_addrolemember '''+ @rolename + ''', ''' + @login + N''';' 
    EXEC sp_executesql @sql 

    -- create user in db2 
    if (@user2 is null) begin 
     SET @sql = N'USE database2; CREATE USER [' + @login + N'] FOR LOGIN [' + @login + N'];' 
     EXEC sp_executesql @sql 
    end 

    -- ensure user is member of role in db2 
    SET @sql = N'USE database2; EXEC sp_addrolemember '''+ @rolename + ''', ''' + @login + N''';' 
    EXEC sp_executesql @sql 

    fetch next from c into @login, @user1, @user2 
end 


close c 
deallocate c 

Si vuole aggiungere una transazione e la gestione di rotolare fuori cambiamenti incompleti errore, ma lascio che a voi.

+0

C'è un modo che questo possa essere fatto per i nuovi utenti aggiunti a 'database1'? – bendataclear

+0

Per ogni utente aggiuntivo che devi aggiungere, usa le parti 'CREATE USER [nome utente] FOR LOGIN [nome login]' e 'exec sp_addrolemember ...' su ogni database (puoi omettere la parte CREATE USER se già creato gli utenti in ogni database, ad esempio, tramite lo studio di gestione). – HackedByChinese

+0

I nuovi utenti vengono aggiunti molto regolarmente e dover eseguire questi script ogni volta potrebbe essere difficile. C'è un modo per rispecchiare gli accessi? – bendataclear

0

Impostare la stored procedure per l'esecuzione come proprietario.

http://msdn.microsoft.com/en-us/library/ms188354.aspx

Impostare affidabile sul database in cui si trova la stored procedure.

http://technet.microsoft.com/en-us/library/ms187861.aspx

Assicurarsi di avere lo stesso proprietario su entrambi i database.

http://msdn.microsoft.com/en-us/library/ms188676(v=sql.105).aspx

Concessione permessi di esecuzione sulla stored procedure per l'utente appropriato o il ruolo sulla base di dati con la procedura.

+0

Ho provato questi quattro passaggi, ma l'errore dell'applicazione si apre ancora, ho anche provato a creare una procedura memorizzata in 'database1' che chiama proc in' database2', ma ha ancora errori. – bendataclear

Problemi correlati