如何添加有权访问单个视图的用户?


14

我正在使用MSSQL Server Management Studio 2008,并且需要向第三方公开其数据协调的视图。我已经创建了适当的视图,但是在创建用户和授予该用户适当的权限以从视图中选择时遇到了麻烦。

我遵循了用于创建登录名和用户的向导,然后在“安全性”部分中添加了我的视图,并选中了“授予”框。一切似乎都很好,但是当我以该用户身份登录并尝试执行“从MyViewName中选择*”时,它告诉我选择权限被拒绝。

我只是重新创建了用户(这次只是使用SQL而不是向导),并明确授予了选择权限,现在它给了我错误:(Msg 916, Level 14, State 1, Line 2 The server principal "username" is not able to access the database "unrelated_db" under the current security context.我不知道为什么它试图访问不相关的数据库...)

我真的不知道从这里去哪里。同样,基本上,我所需要做的就是创建一个我可以提供给第三方的用户,以使他们连接到我们的数据库并从该视图中进行选择。


3
视图是否引用其他数据库中的基表?如果是这样,则必须处理所有权链接。另外,请确保您当前已将数据库上下文设置为所需的数据库。
Thomas Stringer

有什么方法可以查看视图的依赖关系吗?我的意思是,据我所知,视图中的所有内容都应包含在主数据库中。该视图仅是三个字段,两个字段来自付款明细表,一个字段来自与帐户明细表的联接,但是两个表都在同一个数据库中(并且与该视图位于同一数据库中)。
velojason 2012年

Answers:


16

请不要为此使用UI。这是一个混乱的混乱。

在我看来,您想要的是在数据库中为特定登录名创建用户,该用户仅具有从一个视图中进行选择的权限。因此,由于您已经创建了登录名:

USE your_db;
GO
CREATE USER username FROM LOGIN username;
GO
GRANT SELECT ON dbo.MyViewName TO username;
GO

此处的编辑是一个脚本示例,该脚本将导致您提到的错误。

首先,在unrelated_db中创建一些表:

CREATE DATABASE unrelated_db;
GO
USE unrelated_db;
GO
CREATE TABLE dbo.foo(bar INT);
GO

现在创建一个相对受限的登录名:

USE [master];
GO
CREATE LOGIN username WITH PASSWORD='foo', CHECK_POLICY = OFF;
GO

现在创建一个将视图保存在其中的数据库,并将登录名添加为用户:

CREATE DATABASE velojason;
GO
USE velojason;
GO
CREATE USER username FROM LOGIN username;
GO

现在创建一个函数,该函数将引用另一个数据库中的表,以及另一个表的同义词:

CREATE FUNCTION dbo.checkbar()
RETURNS INT
AS 
BEGIN
    RETURN 
    (
      SELECT TOP (1) bar 
        FROM unrelated_db.dbo.foo 
        ORDER BY bar
    );
END
GO
CREATE SYNONYM dbo.foo FOR unrelated_db.dbo.foo;
GO

现在创建一个本地表:

CREATE TABLE dbo.PaymentDetails
(
  PaymentID INT
);
GO

现在创建一个观点,即引用表,函数和同义词,并授予SELECTusername

CREATE VIEW dbo.SomeView
AS
  SELECT 
    p.PaymentID, 
    x = dbo.checkbar(), -- function that pulls from other DB
    y = (SELECT bar FROM dbo.foo) -- synonym to other DB
    FROM dbo.PaymentDetails AS p;
GO
GRANT SELECT ON dbo.SomeView TO username;
GO

现在尝试执行为,username并从视图中仅选择本地列:

EXECUTE AS USER = 'username';
GO
  -- even though I don't reference any of the columns 
  -- in the other DB, I am denied SELECT on the view:
SELECT PaymentID FROM dbo.SomeView;
GO
REVERT;
GO

结果:

消息916,级别14,状态1,第3
行在当前安全上下文下,服务器主体“用户名”无法访问数据库“ unrelated_db”。

现在将视图更改为不引用任何外部对象,然后SELECT再次运行上面的命令,它可以工作:

ALTER VIEW dbo.SomeView
AS
  SELECT 
    p.PaymentID 
    --x = dbo.checkbar(),
    --y = (SELECT bar FROM dbo.foo)
    FROM dbo.PaymentDetails AS p;
GO

如果没有向我们显示付款明细,帐户明细和MyView对象的脚本,也许您可​​以让我们知道该查询是否返回任何结果。您可以通过目录视图找到对各种对象的引用sys.sql_expression_dependencies,但是这种视图不是完美的-我相信它取决于按顺序刷新的所有视图(例如,在视图引用其他视图或基础架构已更改的情况下)准确地说。

DECLARE 
  @dbname   SYSNAME = N'unrelated_db',
  @viewname SYSNAME = N'dbo.SomeView';

SELECT DISTINCT 
    [This object] = 
    OBJECT_SCHEMA_NAME([referencing_id]) 
      + '.' + OBJECT_NAME([referencing_id]), 
    [references this object] = 
    OBJECT_SCHEMA_NAME([referenced_id]) 
      + '.' + OBJECT_NAME([referenced_id]), 
    [and touches this database] = referenced_database_name,
    [and is a(n)] = o.type_desc,
    [if synonym, it references] = s.base_object_name
FROM sys.sql_expression_dependencies AS d
LEFT OUTER JOIN sys.objects AS o
ON o.[object_id] = d.referenced_id
LEFT OUTER JOIN sys.synonyms AS s
ON d.referenced_id = s.[object_id]
AND s.base_object_name LIKE '%[' + @dbname + ']%'
WHERE OBJECT_ID(@viewname) IN (
        referenced_id, 
        referencing_id, 
        (SELECT referencing_id FROM sys.sql_expression_dependencies 
        WHERE referenced_database_name = @dbname)
) OR referenced_database_name = @dbname;

SQL Server不仅会尝试从中获得unrelated_db乐趣,而且还需要从您要使用的视图中对该数据库进行一定的限制。不幸的是,如果我们看不到视图定义以及它所涉及的对象的更多详细信息,我们所能做的就是推测。我能想到的两个主要问题是使用三部分名称的同义词或函数,但是看到实际的脚本将为我们提供一个更好的主意,而不是猜测。:-)

您可能还需要检查sys.dm_sql_referenced_entities,但是该函数在上面的示例中没有返回任何有用的信息。


6
create login YourTpvLogin with password = 'enter new password here'
go

use SomeDb
go

create user YourTpvUser for login YourTpvLogin
go

grant select on YourView to YourTpvUser
go

您可以通过执行以下操作对此进行测试:

execute as user = 'YourTpvUser'
go

select *
from YourView

revert
go

显然,这不会递归地授予特权。允许用户从“ YourView”中进行选择,但是如果“ YourView”依赖于其他关系/数据库,它将失败:服务器主体“ YourTpvUser”在当前安全上下文下无法访问数据库“ OtherDb”。
lilalinux13年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.