gbn*_*gbn 25 permissions schema encapsulation sql-server-2005 sql-server-2008
受到我见过的各种架构相关问题的启发......
如果存储过程和表都在同一模式中,则所有权链接允许我对存储过程进行GRANT EXECUTE,而不对我使用的表具有显式权限.
如果我们使用单独的模式,那么我必须在不同的模式表上显式GRANT XXX.所有权链接示例证明了这一点.这意味着存储的proc执行用户可以直接读/写表.
这就像直接访问类中的实例变量一样,绕过getter/setter,打破封装.
我们还使用行级安全性来限制某人看到的内容,并将其应用于存储过程.
那么,我们如何维护模式分离并防止直接表访问?
当然,如果您使用ORM或不使用存储过程,则该问题将不适用.但我不会问我是否应该使用ORM或存储过程,以防有人觉得需要启发我...
编辑,例如
CREATE USER OwnsMultiSchema WITHOUT LOGIN
GO
CREATE SCHEMA MultiSchema1 AUTHORIZATION OwnsMultiSchema
GO
CREATE SCHEMA MultiSchema2 AUTHORIZATION OwnsMultiSchema
GO
CREATE USER OwnsOtherSchema WITHOUT LOGIN
GO
CREATE SCHEMA OtherSchema AUTHORIZATION OwnsOtherSchema
GO
CREATE TABLE MultiSchema1.T1 (foo int)
GO
CREATE TABLE MultiSchema2.T2 (foo int)
GO
CREATE TABLE OtherSchema.TA (foo int)
GO
CREATE PROC MultiSchema1.P1
AS
SELECT * FROM MultiSchema1.T1
SELECT * FROM MultiSchema2.T2
SELECT * FROM OtherSchema.TA
Go
EXEC AS USER = 'OwnsMultiSchema'
GO
--gives error on OtherSchema
EXEC MultiSchema1.P1
GO
REVERT
GO
CREATE PROC OtherSchema.PA
AS
SELECT * FROM MultiSchema1.T1
SELECT * FROM MultiSchema2.T2
SELECT * FROM OtherSchema.TA
Go
GRANT EXEC ON OtherSchema.PA TO OwnsMultiSchema
GO
EXEC AS USER = 'OwnsMultiSchema'
GO
--works
EXEC OtherSchema.PA
GO
REVERT
GO
Run Code Online (Sandbox Code Playgroud)
编辑2:
RBa*_*ung 22
我担心你的描述或你对所有权链的概念都不清楚,所以让我从这开始:
"所有权链接"简单地指的是当在SQL Server上执行存储过程(或视图)时,当前正在执行的批处理在执行该SQL代码时临时获取sProc所有者(或sProc的模式所有者)的权限/权限.因此,对于sProc,用户不能使用这些priv来执行sProc代码未实现的任何操作. 特别要注意的是,它永远不会获得所有者的身份,只会获得它的权利(但是,EXECUTE AS ...会这样做).
因此,将此用于安全性的典型方法是:
将所有数据表(以及所有非安全性视图)放入他们自己的Schema中,让我们将其称为[数据](尽管通常使用[dbo],因为它已经存在并且对于用户的模式来说太特权了).确保没有现有的用户,架构或所有者可以访问此[data]架构.
为所有sProc(和/或可能的任何安全视图)创建一个名为[exec]的模式.确保此模式的所有者可以访问[data]模式(如果您将dbo作为此模式的所有者,这很容易).
创建一个名为"Users"的新db-Role,并为其提供对[exec]模式的EXECUTE访问权限.现在将所有用户添加到此角色.确保您的用户仅具有Connect权限,并且没有授予对任何其他架构的授予访问权限,包括[dbo].
现在,您的用户只能通过执行[exec]中的sProcs来访问数据.他们无法访问任何其他数据或执行任何其他对象.
我不确定这是否能回答你的问题(因为我不确定问题究竟是什么),所以请随意重定向我.
至于行级安全性,以下是我总是如何使用上面的安全方案:
我总是将行级安全性实现为一系列视图,这些视图对每个表进行镜像封装,并将用户的身份(通常与Suser_Sname()或其中一个进行比较)与从行本身的安全代码中键入的安全列表进行比较.这些是安全视图.
创建一个名为[rows]的新模式,让它的所有者访问[data]模式,而不是任何其他模式.将所有Security-Views放在此架构中.
撤消[exec]所有者对[data]架构的访问权限,并授予其对[rows]架构的数据访问权限.
完成.现在,行级安全性已通过在sProcs和表之间透明地滑动来实现.
最后,这是一个存储的采购,我用它来帮助我记住这些模糊的安全性有多少工作并与自身交互(oops,更正版本的代码):
CREATE proc [TestCnxOnly].[spShowProc_Security_NoEX] as
--no "With Execute as Owner" for this version
--create User [UserNoLogin] without login
--Grant connect on database :: TestSecurity to Guest
--alter database TestSecurity set trustworthy on
--Show current user context:
select current_user as current_
, session_user as session
, user_name() as _name
, suser_name() as [suser (sproc)]
, suser_sname() as sname
, system_user as system_
--Execute As Login = 'UserNoLogin'
select current_user as current_
, session_user as session
, user_name() as _name
, suser_name() as [suser (after exec as)]
, suser_sname() as sname
, system_user as system_
EXEC('select current_user as current_
, session_user as session
, user_name() as _name
, suser_name() as [suser (in Exec(sql))]
, suser_sname() as sname
, system_user as system_')
EXEC sp_ExecuteSQL N'select current_user as current_
, session_user as session
, user_name() as _name
, suser_name() as [suser (in sp_Executesql)]
, suser_sname() as sname
, system_user as system_'
--Revert
select current_user as current_
, session_user as session
, user_name() as _name
, suser_name() as [suser (aftr revert)]
, suser_sname() as sname
, system_user as system_
Run Code Online (Sandbox Code Playgroud)
[编辑:更正版本的代码)
我的2c:所有权链接是遗产.它可以追溯到没有替代品的日子,与今天的替代品相比,它是不安全和粗糙的.
我说备选方案不是架构权限,另一种方法是代码签名.使用代码签名,您可以授予对过程签名所需的权限,并在严格控制数据访问时授予对过程的广泛执行访问权限.代码签名提供更细粒度和更精确的控制,并且不能以所有权链接的方式滥用.它在模式中工作,它在模式中工作,它在数据库中工作,并且不需要打开跨数据库所有权链的巨大安全漏洞.并且它不需要为了访问目的而劫持对象所有权:过程的所有者可以是任何用户.
至于关于行级安全性的第二个问题:作为引擎提供的功能,SQL Server版本2014及更早版本中并不存在行级安全性.您有各种变通方法,这些变通办法在代码签名方面比使用所有权链接更有效.由于sys.login_token包含上下文签名和副签名,因此您实际上可以执行比在所有权链接上下文中更复杂的检查.
自2016版本以来,SQL Server完全支持行级安全性.
小智 5
你可以:
Grant Execute On Schema::[schema_name] To [user_name]
Run Code Online (Sandbox Code Playgroud)
允许用户执行模式中的任何过程。如果您不希望他能够执行所有这些,您可以明确拒绝对用户执行特定程序。在这种情况下,拒绝优先。
| 归档时间: |
|
| 查看次数: |
61920 次 |
| 最近记录: |