跨数据库访问在Windows组上不起作用?

时间:2014-12-04 16:03:58

标签: sql-server

我已创建了一个Windows组domain\group,并将Windows用户domain\user1添加到该组中。然后创建登录

use master
create login [domain\group] for windows 
use myDB
create user [domain\group] for login [domain\group]
grant select on schema::mySchema to [domain\group]

我启用了跨数据库访问

use master
EXECUTE sp_configure 'show advanced', 1;
RECONFIGURE with override;
EXECUTE sp_configure 'cross db ownership chaining', 1;
RECONFIGURE with override;

以下声明有效。

exec ('select 1 a') as login = 'domain\user'

但是,在选择访问另一个数据库中的表的视图时出现以下错误。

create view mySchema.view1 as select * from anotherDb.dbo.table1
go
exec ('select * from mySchema.view1') as login = 'domain\user' 

Msg 916, Level 14, State 1, Line 1 The server principal "domain\user1" is not able to access the database "anotherDb" under the current security context.

1 个答案:

答案 0 :(得分:1)

根据此MSDN文章,如果您使用的是动态SQL,则用户必须存在于两个数据库中(或者如果过程由两个数据库中都存在的证书签名)。 http://msdn.microsoft.com/en-us/library/bb669059(v=vs.110).aspx

  

跨数据库所有权链接在以下情况下不起作用   除非同一个用户,否则将执行动态创建的SQL语句   存在于两个数据库中。您可以在SQL Server中解决此问题   创建一个访问另一个数据库中的数据的存储过程   使用两者中存在的证书签署该过程   数据库。这使用户可以访问所使用的数据库资源   该程序没有授予他们数据库访问权限。

确保数据库拥有相同的所有者:

select d.name, d.owner_sid, owner_name = suser_sname(d.owner_sid) 
from sys.databases d 
where d.name in ('myDB','anotherDB')

同时使用下面的查询检查每个数据库中的数据库对象是否具有相同的owner_login(并且owner_login不应该是NULL),否则所有权链将被破坏:

use myDB
go

select o.name, o.type_desc
    , owner_name = USER_NAME(OBJECTPROPERTY(o.object_id, 'OwnerId'))
    , owner_login = suser_sname(p.sid)
from sys.objects o 
left join sys.database_principals p on p.principal_id = OBJECTPROPERTY(o.object_id, 'OwnerId') 
where o.name = 'view1'
and o.schema_id = schema_id('mySchema')
go

use anotherDB
go

select o.name, o.type_desc
    , owner_name = USER_NAME(OBJECTPROPERTY(o.object_id, 'OwnerId'))
    , owner_login = suser_sname(p.sid)
from sys.objects o 
left join sys.database_principals p on p.principal_id = OBJECTPROPERTY(o.object_id, 'OwnerId') 
where o.name = 'table1'
and o.schema_id = schema_id('dbo')
go