2012-06-18 8 views
5

Versión corta: ¿Puedo otorgar acceso a bases de datos externas a un rol?Otorgando acceso a un db a usuarios/roles de otro

Versión larga:

estoy trabajando en informes utilizando Crystal que está recuperando datos de una aplicaciones instancia de SQL Server (database1).

La aplicación está ejecutando los informes y sobrescribiendo la conexión en el informe, no tengo acceso al código de las aplicaciones.

He agregado una nueva base de datos al servidor (database2) que está recopilando información de una central telefónica y deseo unir parte de esta información a los datos de la aplicación (database1).

Puedo unir los datos y los informes funcionan cuando se ejecutan dentro del diseñador (inicia sesión como SA) pero cuando los informes se ejecutan externamente a través de la aplicación fallan con un error bastante genérico (Error al recuperar datos).

Supongo que el error está causado por los nuevos permisos DB, como si iniciara sesión en la aplicación como SA el error desaparece.

La aplicación tiene un rol de base de datos especial para los usuarios que ejecutan informes al agregar una tabla/vista/sp a la aplicación db (database1). Simplemente puedo otorgar seleccionar/ejecutar esta función para permitir que los informes accedan al objeto .

Ahora tengo el objeto en un db diferente, pero no se puede acceder fácilmente al rol.

¿Hay alguna manera de que pueda hacer referencia al segundo db (database2) a través del rol existente?

por ejemplo:

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

OR 

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

Lo ideal sería que quieren ser capaces de vincular a la Función de alguna manera en lugar de volver a crear un nuevo papel como el papel se actualiza mediante la aplicación regularmente cuando se añaden/configuran nuevos usuarios.

(No etiquetados con Crystal-Reports ya que esto no está relacionado con el problema)

Editar:

¿Hay alguna manera de hacer algo como:

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

¿Para copiar a los usuarios (no inicios de sesión) y luego agregar los miembros de la función?

Respuesta

3

Presumiblemente, estaría utilizando un inicio de sesión que tiene acceso a ambas bases de datos (como el caso de SA). Debería crear el rol apropiado y otorgar derechos a cada base de datos, luego crear el usuario (vinculado al inicio de sesión que está utilizando) en ambos, agregando cada uno al rol que creó.

El T-SQL se verá algo como esto:

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 

Ahora puede conectarse a test y ejecutar

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

Por supuesto, usted cambia sus subvenciones para ejecutar en el deseado procedimientos almacenados, pero parece que ya lo tienes cubierto.

Después de eso, se trata simplemente de ejecutar una secuencia de comandos simple para crear inicios de sesión, usuarios y agregarlos a la función. inicios de sesión

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 

la sincronización, los usuarios y los roles de forma automática

Este script encontrará todos los inicios de sesión SQL (se puede cambiar esto a lo que tenga sentido para ti, las ventanas y las cuentas SQL, cuentas que contengan una determinada cadena, lo que sea), asegúrese de que el usuario se haya creado en database1 y database2, y se asegura de que ambos se agreguen al rol reporting. Deberá asegurarse de que se crea el rol reporting en ambas bases de datos, pero solo necesita hacerlo una vez.

Después de eso, puede ejecutar esta secuencia de comandos periódicamente, ya sea manualmente o utilizando un trabajo del Agente de SQL. Todo lo que necesita hacer es crear el inicio de sesión para el servidor; cuando se ejecuta el script, hará el 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 

Usted tendrá que añadir una transacción y gastos de envío a rodar fuera de cambios incompletos error, pero voy a dejar que depende de usted.

+0

¿Hay alguna forma de que esto se pueda hacer para los usuarios nuevos que se agregan a 'database1'? – bendataclear

+0

Para cualquier usuario adicional que necesite agregar, solo use las partes 'CREATE USER [nombre de usuario] FOR LOGIN [nombre de usuario]' y 'exec sp_addrolemember ...' en cada base de datos (Puede omitir la parte CREATE USER si ya creado los usuarios en cada base de datos, por ejemplo, a través de un estudio de administración). – HackedByChinese

+0

Se agregan nuevos usuarios muy regularmente y tener que ejecutar estos scripts cada vez puede ser difícil. ¿Hay alguna forma de reflejar los inicios de sesión? – bendataclear

0

Establezca el procedimiento almacenado para ejecutar como propietario.

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

Establecer confianza en la base de datos donde se encuentra el procedimiento almacenado.

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

Asegúrese de que tiene el mismo propietario en ambas bases de datos.

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

subvención permisos de ejecución en el procedimiento almacenado para el usuario o el papel apropiado en la base de datos con el procedimiento.

+0

He intentado estos cuatro pasos, pero el error de la aplicación todavía aparece, también he intentado crear un procedimiento almacenado en 'database1' que llama al proceso en' database2' pero todavía hay errores. – bendataclear

Cuestiones relacionadas