Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Concedendo acesso a um banco de dados para usuários/funções de outro


Presumivelmente, você estaria usando um login que tem acesso a ambos os bancos de dados (como o caso do SA). Você criaria a função apropriada e concederia direitos a cada banco de dados e, em seguida, criaria o usuário (vinculado ao login que está usando) em ambos, adicionando cada um à função que você criou.

O T-SQL ficará assim:
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

Agora posso me conectar ao test e executar
 select * from something
 select * from test2.dbo.something2

Claro, você mudaria suas concessões para EXECUTE nos procedimentos armazenados desejados, mas parece que você já cobriu isso.

Depois disso, basta executar um script simples para criar logins, usuários e adicioná-los à função.
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

Sincronizando logins, usuários e funções automaticamente


Este script encontrará todos os logins SQL (você pode alterar isso para o que fizer sentido para você; Windows AND SQL accounts, contas que contêm uma determinada string, o que for), verifique se o usuário foi criado em database1 e database2 , e garante que ambos sejam adicionados ao reporting Função. Você precisará garantir o reporting função é criada em ambos os bancos de dados, mas você só precisa fazer isso uma vez.

Depois disso, você pode executar esse script periodicamente, manualmente ou usando um trabalho do SQL Agent. Tudo que você precisa fazer é criar o login para o servidor; quando o script for executado, ele fará o 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

Você desejará adicionar uma transação e tratamento de erros para liberar alterações incompletas, mas deixarei isso para você.