2012-06-18 7 views
5

短いバージョン:外部データベースへのアクセスをロールに付与できますか?別のユーザー/ロールに1つのデータベースへのアクセスを許可する

ロングバージョン:

私は、アプリケーションのSQL Serverインスタンス(database1)からデータを取得しているクリスタルを使用してレポートに取り組んでいます。

アプリケーションがレポートを実行しており、レポート内の接続を上書きすると、アプリケーションコードにアクセスできません。

電話交換機から情報を収集しているサーバーに新しいDBを追加しました。この情報の一部をアプリケーションデータ(database1)に追加します。

私はデータに参加することができ、デザイナー(SAとしてログイン)で実行されたときにレポートが機能しますが、アプリケーションから外部でレポートを実行すると、かなり一般的なエラー(データの取得に失敗しました)で失敗します。

私は、エラーがなくなるとSAとしてアプリケーションにログインしたようなエラーが新しいDB権限によって引き起こされていると仮定しています。

アプリケーションには、テーブル/ビュー/ spをアプリケーションdb(database1)に追加するときに、レポートを実行するユーザーに特別なDBロールがあります。このロールにselect/executeを付与するだけで、 。

今は別のデータベースにオブジェクトがありますが、役割には簡単にアクセスできません。

既存のロールで2番目のdb(database2)を参照できる方法はありますか?

例:

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

OR 

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

は、理想的には私が役割にリンク何とかではなく、ロールが新しいユーザーを追加/設定されている定期的にアプリケーションによって更新され、新しい役割を再作成することができるようにしたいです。

(これは問題に関連していないとして、クリスタル・レポートでタグ付けされていない)

編集:

のようなものを行うにはどのような方法があります:

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

ユーザー(ログインではなく)をコピーして役割メンバーを追加するには?

答えて

3

おそらく、両方のデータベースにアクセスできるログインを使用しているとします(SAの場合など)。適切なロールを作成して各データベースに権限を与え、両方のロールで使用しているログインにリンクしているユーザーを作成したロールに追加します。

T-SQLには、次のようになります。今、私はtestに接続し、もちろん

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

を実行することができ

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 

、あなたが希望に実行するように助成金を変更したいですストアドプロシージャは、すでにカバーされているように見えます。

その後、単純なスクリプトを実行してログイン、ユーザーを作成し、役割に追加します。

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 

の同期のログイン、ユーザー、および役割自動的

このスクリプトは、あなたがあなたに理にかなって何にこれを変更することができます(すべてのSQLログインを見つけます。WindowsとSQLアカウント、特定の文字列を含むアカウント、ユーザーがdatabase1database2で作成され、両方がreportingロールに追加されていることを確認します。両方のデータベースでreportingロールが作成されていることを確認する必要がありますが、これは一度だけ行う必要があります。

その後、手動で、またはSQLエージェントジョブを使用して、このスクリプトを定期的に実行できます。サーバーのログインを作成するだけです。スクリプトが実行されると、残りの処理が実行されます。

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 

あなたが取引や不完全な変更をロールオフするエラー処理を追加したいと思うでしょうが、私はあなたにそれを任せます。

+0

これは、 'database1'に追加された新しいユーザに対して行うことができますか? – bendataclear

+0

追加する必要のあるユーザは、各データベースで 'CREATE USER [ユーザ名] FOR LOGIN [ログイン名]'と 'exec sp_addrolemember ...'部分を使用するだけです(CREATE USER部分は省略できます管理スタジオを介して、各データベースのユーザーを作成しました)。 – HackedByChinese

+0

新規ユーザーは非常に定期的に追加され、毎回これらのスクリプトを実行しなければならない場合があります。ログインをミラーリングする方法はありますか? – bendataclear

0

オーナーとして実行するストアドプロシージャを設定します。ストアドプロシージャが配置されているデータベースに信頼できる設定

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

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

あなたは両方のデータベースで同じ所有者があることを確認してください。

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

グラント手順を使用して、データベース上の該当するユーザーまたはロールにストアドプロシージャの実行権限。

+0

私はこれらの4つのステップを試しましたが、アプリケーションエラーがまだポップアップしていますが、 'database2'のprocを呼び出す' database1'のストアドプロシージャも作成しようとしましたが、それでもエラーです。 – bendataclear

関連する問題