我使用跨数据库证书(如 Erland Sommarskog 所述)来控制对我环境中某个数据库的访问(SQL Server 2008 R2)。
我在数据库 A 中存储了更新数据库 B 中表的存储过程。直到现在,这一直适用于 db A 中的各种存储过程和 db B 中的表。我正在尝试更新 db B 中的表,但该表上有一个触发器。此触发器在 db B 的另一个表中插入其他数据。我收到错误消息:
消息 916,级别 14,状态 1,过程 table_trigger,第 11 行 服务器主体“sql\login”在当前安全上下文下无法访问数据库“B”。
我尝试为与证书绑定的数据库 B 用户授予插入权限以插入其他表,但它没有解决错误。除了更改触发器以使其使用之外,我还有其他选择WITH EXECUTE AS OWNER
吗?
这是复制问题的 DDL:
CREATE LOGIN [GuggTest] WITH PASSWORD=N'abcd', DEFAULT_DATABASE=[master], CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF
CREATE DATABASE A;
CREATE DATABASE B;
USE A;
CREATE TABLE dbo.SPtoUpdate
(
ID INT
, ILoveFishing VARCHAR(255)
);
INSERT INTO dbo.SPtoUpdate
( ID , ILoveFishing )
VALUES ( …
Run Code Online (Sandbox Code Playgroud) 客户要求我实施一些用于报告目的的视图,这些视图将通过 PowerBI、Excel 和 SSRS 访问。指定的用户将只能访问该视图,并且该用户必须不能使用任何基础表。
我遇到的问题是视图中的 SQL 涉及 3 个不同的模式(都在同一个数据库中):
观点是:
CREATE VIEW dbo.vTestPermissions
AS
SELECT a.Column1,
b.Column1,
c.Column1
FROM Pupil.Table1 a
JOIN Provider.Table2 b ON a.Column1 = b.Column1
JOIN Security.Table3 c ON a.Column1 = c.Column1
Run Code Online (Sandbox Code Playgroud)
表/视图的所有者如下:
当我从视图中选择时,出现错误:
对象“table3”、数据库“TEST”、架构“Security”的 SELECT 权限被拒绝
我曾尝试在SELECT
有和没有GRANT
模式和表选项的情况下授予权限,但这使用户可以使用基础表。
对此的任何帮助将不胜感激。
我有一种情况,虽然我能够解决它(如重现所示),但我不明白。以下是重点
EXEC(@sql)
访问 ChainingDestination 中的表execute as
子句定义的execute as
条款,我会得到同样的错误。execute as
条款,一切都很好。这是我感到困惑的倒数第二点。或者,具体地,为什么一个不工作,最后一个呢。
/******************************
Setup
******************************/
USE [master];
go
IF EXISTS (SELECT 1 FROM [sys].[databases] WHERE [name] = 'ChainingSource')
BEGIN
ALTER DATABASE [ChainingSource] SET OFFLINE WITH ROLLBACK IMMEDIATE;
ALTER DATABASE [ChainingSource] SET ONLINE;
DROP DATABASE [ChainingSource];
END
IF EXISTS (SELECT 1 FROM [sys].[databases] WHERE [name] = 'ChainingDestination')
BEGIN
ALTER DATABASE [ChainingDestination] SET OFFLINE WITH …
Run Code Online (Sandbox Code Playgroud) 我必须承认我不是 DBA,但我需要维护一个 SQL Server 实例,并且存储过程权限链几乎没有问题(希望条款是正确的)。
为了简要解释我的需求,我有一个用户应该只在一个数据库上授予权限,该数据库应该运行一个存储过程(在该“授予”数据库上),该存储过程包含对外部数据库的引用(我应该继承一些授予)
详细来说,我的情况是我有三个数据库
所以我有三个用户
到目前为止一切顺利,暂存过程完成其工作,并在完成后写入信号量(通知数据已准备好)。有时,应用程序(使用最终用户)会检查信号量并将所有数据提取到最终数据库中。
现在我必须支持快速、按需的暂存过程(由于其他原因我仍然需要从暂存数据库执行),该过程完成后,应直接将数据更新到最终数据库中。
我已经编写了这样的过程,一切都按预期工作,但我必须将 FinalDB 上的读/写操作授予暂存用户,我不喜欢它。有许多应用程序使用临时用户,其中一些应用程序不在“我的控制之下”,因此我不希望将数据写入临时数据库的错误应用程序最终会弄乱最终数据库。我可以接受我的新的按需暂存过程可能很关键(并且最终会弄乱最终数据库)。
所以问题是,暂存用户已被授予执行存储过程(EG:OnDemandUpdate)的权限,因为它是暂存数据库的一部分,但包含对外部表(来自最终数据库)的插入/更新,并且我希望该授权可以是被束缚。我怎样才能做到这一点?
我们有两个数据库,Adb
和Bdb
. 在Bdb
,我们创建了一个观点,即引用另一种观点认为Adb
,像这样:CREATE VIEW Bdb.dbo.Bview AS SELECT * FROM Adb.dbo.Aview
。
我们有一个 SQL Authenticated Blogin
,映射到Buser
,Adb
和Bdb
,至少db_datareader
在两者上都有角色。
以下不起作用:
USE Bdb;
EXECUTE AS USER = 'Buser';
SELECT * FROM Bdb.dbo.Bview;
SELECT * FROM Adb.dbo.Aview;
Run Code Online (Sandbox Code Playgroud)
两个选择都会引发以下错误:
Msg 916, Level 14, State 1, Line 4
The server principal "Buser" is not able to access the database "Adb" under the current security context.
Run Code Online (Sandbox Code Playgroud)
但是,这有效:
USE Adb;
EXECUTE AS USER …
Run Code Online (Sandbox Code Playgroud) sql-server ×5
permissions ×4
certificate ×2
signature ×2
owner ×1
security ×1
trigger ×1
users ×1
view ×1