You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何对拥有VIEW ANY DATABASE权限的登录者隐藏指定SQL Server数据库

解决方案

一、优先隐藏目标数据库(推荐)

如果用户的VIEW ANY DATABASE权限来自默认的public服务器角色,可通过在目标数据库上拒绝两项核心权限,让所有非特权用户无法看到该数据库:

USE [目标数据库名];
GO
-- 拒绝public角色查看数据库定义
DENY VIEW DEFINITION ON DATABASE::[目标数据库名] TO public;
-- 拒绝public角色查看数据库状态
DENY VIEW DATABASE STATE ON DATABASE::[目标数据库名] TO public;
GO

执行后,所有属于public角色且无更高权限(如sysadmin、db_owner)的登录用户,无论是在对象资源管理器还是执行SELECT name FROM sys.databases,都无法看到该数据库,且完全不影响他们对其他数据库的访问。

注意事项

  • 若部分用户单独拥有服务器级的VIEW DEFINITION权限(优先级高于数据库级拒绝),需单独针对这些用户执行拒绝操作。

二、批量限制数据访问(隐藏不可行时)

如果无法完全隐藏数据库,可通过自定义数据库角色批量配置拒绝权限,避免逐个指定用户:

  1. 创建自定义拒绝角色
USE [目标数据库名];
GO
CREATE ROLE db_deny_restricted_access;
-- 拒绝角色对数据库的所有SELECT权限
DENY SELECT ON DATABASE::[目标数据库名] TO db_deny_restricted_access;
-- 可选:同时拒绝查看数据库内对象的定义
DENY VIEW DEFINITION ON DATABASE::[目标数据库名] TO db_deny_restricted_access;
GO
  1. 批量添加符合条件的用户到角色
    通过动态SQL,自动将所有拥有VIEW ANY DATABASE权限的登录对应的数据库用户(已存在的)添加到该角色:
USE [目标数据库名];
GO
DECLARE @sql NVARCHAR(MAX) = N'';

SELECT @sql += N'
ALTER ROLE db_deny_restricted_access ADD MEMBER [' + dp.name + N'];'
FROM sys.database_principals dp
JOIN sys.server_principals sp ON dp.sid = sp.sid
WHERE sp.type IN ('S', 'U', 'G') -- 覆盖SQL登录、Windows登录、Windows组
AND EXISTS (
    SELECT 1 FROM sys.server_permissions spm
    WHERE spm.grantee_principal_id = sp.principal_id
    AND spm.permission_name = 'VIEW ANY DATABASE'
    AND spm.state IN ('G', 'W') -- 筛选已授予或带授予权限的用户
);

EXEC sp_executesql @sql;
GO

补充:处理未映射的登录

如果有部分登录尚未在目标数据库中创建用户,可先批量创建用户再添加到角色:

USE [目标数据库名];
GO
DECLARE @createSql NVARCHAR(MAX) = N'', @addRoleSql NVARCHAR(MAX) = N'';

SELECT 
    @createSql += N'CREATE USER [' + sp.name + N'] FOR LOGIN [' + sp.name + N'];',
    @addRoleSql += N'ALTER ROLE db_deny_restricted_access ADD MEMBER [' + sp.name + N'];'
FROM sys.server_principals sp
WHERE sp.type IN ('S', 'U', 'G')
AND EXISTS (
    SELECT 1 FROM sys.server_permissions spm
    WHERE spm.grantee_principal_id = sp.principal_id
    AND spm.permission_name = 'VIEW ANY DATABASE'
    AND spm.state IN ('G', 'W')
)
AND NOT EXISTS (
    SELECT 1 FROM sys.database_principals dp
    WHERE dp.sid = sp.sid
);

EXEC sp_executesql @createSql;
EXEC sp_executesql @addRoleSql;
GO

三、权限验证

操作完成后,切换到目标登录账号,执行以下语句验证效果:

-- 检查是否能看到目标数据库
SELECT name FROM sys.databases WHERE name = '目标数据库名';
-- 检查是否能读取表数据
SELECT * FROM [目标数据库名].[dbo].[目标表名];

内容的提问来源于stack exchange,提问作者TK Bruin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 16:25:33