为 SQL 用户设置对所有对象的权限

Dav*_*rge 1 security database-design sql-server

我有一个过程,它遍历数据库中的所有对象并为它们分配适当的权限给该对象。我想知道是否有更好的方法来做到这一点?我使用模型数据库来创建新数据库,因此每次创建新数据库时都必须运行它。这是它的外观的一个想法(注意:从一开始就丢失了一个块,它会删除所有用户并重新创建必要的用户;自从 SID 更改后,这是必要的):

CREATE PROCEDURE usp_SetPermissions 
AS 
 BEGIN

DECLARE @CurrentId INT
DECLARE @ObjectName NVARCHAR(128)
DECLARE @Message NVARCHAR(160)
DECLARE @Error INT
DECLARE @Sql NVARCHAR(256)

CREATE TABLE #tmpDbObjects 
(
   ID INT IDENTITY(1,1),
   ObjectName NVARCHAR(128),
   Completed BIT
)

INSERT #tmpDbObjects(ObjectName, Completed)
SELECT DISTINCT [Name], 0 As Completed 
FROM sys.objects 
WHERE [type] = 'U' AND is_ms_shipped <> 1

WHILE EXISTS (SELECT 1 FROM #tmpDbObjects)
 BEGIN
    -- Pick first uncompleted object
    SELECT TOP 1 @CurrentId = ID,
                 @ObjectName = ObjectName
    FROM #tmpDbObjects

    -- Grant permissions to DB user
    SET @Sql = 'GRANT SELECT, INSERT, UPDATE, DELETE ON dbo.' + QUOTENAME(@ObjectName) + ' TO ' + QUOTENAME(DB_NAME()) 
    EXEC sp_sqlexec @Sql

    -- Update object completion 
    DELETE #tmpDbObjects
    WHERE [Id] = @CurrentId

    -- Clear variables
    SET @Sql = NULL
    SET @CurrentId = NULL
 END

INSERT #tmpDbObjects(ObjectName, Completed)
SELECT DISTINCT [Name], 0 As Completed 
FROM sys.objects 
WHERE [type] = 'P' AND is_ms_shipped <> 1

WHILE EXISTS (SELECT 1 FROM #tmpDbObjects)
     BEGIN
    -- Pick first uncompleted object
    SELECT TOP 1 @CurrentId = ID,
                 @ObjectName = ObjectName
    FROM #tmpDbObjects

    -- Grant permissions to DB user
    SET @Sql = 'GRANT EXEC ON dbo.' + QUOTENAME(@ObjectName) + ' TO ' + QUOTENAME(DB_NAME()) 
EXEC sp_sqlexec @Sql

    -- Update object completion 
    DELETE #tmpDbObjects
    WHERE [Id] = @CurrentId

    -- Clear variables
    SET @Sql = NULL
    SET @CurrentId = NULL
 END
Run Code Online (Sandbox Code Playgroud)

此脚本继续为数据库中的所有视图、函数等执行类似的操作。任何加快这件事的想法还是有更好的方法来做到这一点?

gbn*_*gbn 6

单行将架构级别的权限授予角色

GRANT EXECUTE SELECT, INSERT, UPDATE, DELETE ON SCHEMA::dbo TO SomeRole
Run Code Online (Sandbox Code Playgroud)

第二行将用户添加到角色

EXEC sp_addrolemember 'SomeRole', 'whatever user'
Run Code Online (Sandbox Code Playgroud)

并在模型中执行此操作,以便所有新数据库继承。

原因,您应该只设置一次权限:

  • 模式是对象的容器。
  • 新对象从架构继承权限
  • 角色是用户的容器
  • 新用户被添加到角色并继承

正如您所发现的,当直接分配给用户时,迁移或恢复数据库可能会丢失对象权限。那为什么要把自己放在那个位置呢?

您还可以使用 SID 创建登录,因此它在您的所有服务器上都是相同的,并且您也不会获得孤立用户。

如果您问了正确的问题,我们本可以为您节省一些编码...

就个人而言,最后,我会说这是“需要拥有”而不是“一揽子做任何事情”的不好做法