SQL Server用Integrated Security连接报SELECT权限被拒绝如何解决
报错信息:The SELECT permission was denied on the object 'Table_Name', database 'DatabaseName', schema 'dbo'
1. 确认实际连接使用的Windows账号
集成安全模式下的登录身份由程序的运行上下文决定,很多权限问题都是因为搞错了实际登录账号:
- 桌面/控制台程序:使用当前登录Windows系统的用户账号
- IIS托管的Web程序:默认使用对应应用程序池的标识账号(格式通常为
IIS AppPool\你的应用池名称) - Windows服务:使用服务属性「登录」页配置的运行账号
你可以在程序中执行以下SQL,获取实际连接的账号信息,避免后续授权错对象:SELECT SUSER_SNAME() AS 登录账号, USER_NAME() AS 数据库用户
2. 校验账号的SQL Server权限配置
使用SQL Server管理员账号登录SSMS,按以下顺序检查配置:
- 首先确认第一步查到的Windows账号已添加为SQL Server的登录名:打开「实例 → 安全性 → 登录名」,找不到对应账号的话新建登录名,选择「Windows身份验证」关联目标Windows账号
- 确认登录名已映射到目标数据库的用户:右键登录名 → 属性 → 用户映射,找到
DatabaseName勾选左侧复选框,关联对应的数据库用户 - 授予表的SELECT权限,可选以下任意一种方式执行SQL:
单表授权(仅给目标表查询权限):
全schema授权(给dbo下所有表查询权限):USE DatabaseName GRANT SELECT ON dbo.Table_Name TO [你的Windows完整账号名]USE DatabaseName GRANT SELECT ON SCHEMA::dbo TO [你的Windows完整账号名]
如果目标Windows账号属于某个已配置SQL权限的Windows用户组,直接给用户组授权即可,无需单独给账号授权。
3. 排查拒绝权限覆盖问题
SQL Server中拒绝权限优先级高于授予权限,若授权后仍报错,执行以下SQL查询账号对目标表的有效权限:USE DatabaseName EXEC sys.xp_permissions @objname = N'dbo.Table_Name', @username = N'你的Windows完整账号名'
如果查询结果中SELECT权限的状态为DENY,需要找到对应用户/用户组/角色的拒绝权限配置,删除该条DENY规则即可。
4. 排查身份模拟问题
如果程序中使用了WindowsIdentity.Impersonate()身份模拟逻辑,或是SQL语句中用到了EXECUTE AS切换执行上下文,需要确认切换后的身份确实拥有目标表的SELECT权限,避免实际运行身份和预期不符。
内容的提问来源于stack exchange,提问作者YeZhuxi

