SQL Server使用视图做权限控制
问题引入
这天老鸟火急火燎的跑到菜鸟旁边,想必是遇到什么难题了:“现在有这么一个场景,假如有三种角色,并且存在层级关系,他们需要访问同一个数据源表,但是需要做权限控制,使得每种角色只能看到自己及以下层级的数据。比如:公司有CEO,Manger和普通的employee三种角色,CEO可以查看CEO、Manager和employee层级的数据;Manger只能查看Manger和employee的数据,不能查看CEO层级;而employee只能查看employee的数据,不能查看CEO和Manager级别的数据。这个在SQL Server有比较简单清爽的实现方法吗?”。老鸟这个问题的确问得非常有水准,这个场景也非常普遍,菜鸟顿时陷入了无边的困境。
问题分析
在关系型数据库SQL Server中,权限的确不能达到行列级别这么细粒度的控制,这也是菜鸟为什么陷入困境的原因。但是,突然菜鸟灵魂出窍,灵光一现,像是被雷劈中一般的感觉:虽然SQL Server基于表无法达到那么细粒度的权限控制,但是我们可以建立视图(VIEW),用视图来建立正式表的行、列过滤,然后在视图对象上做权限控制,最终达到对三个层级的权限控制的目的,想到这里菜鸟立马赫然开朗。
解决问题
菜鸟越想越激动,说打就打,说干就干,于是开始了万里长征。
测试环境准备
创建测试数据库Test,接着创建三个用户CEO,Manager和employee,然后创建测试表tb_Test_ViewPermission,最后插入三条测试数据,每个层级一条数据。
IF DB_ID('Test') IS NULLCREATE DATABASE Test;
GOUSE Test
GO--create three logins(CEO, manager, employee)
--create login CEO
IF EXISTS(SELECT *FROM sys.sysloginsWHERE name = 'CEO')
BEGINDROP LOGIN CEO;
END
GO
CREATE LOGIN CEO with password='CEODbo',check_policy = off;
GO--create user CEO
IF USER_ID('CEO') is not nullDROP USER CEO;
GO
CREATE USER CEO FOR LOGIN CEO;
GO--create login Manager
IF EXISTS(SELECT *FROM sys.sysloginsWHERE name = 'Manager')
BEGINDROP LOGIN Manager;
END
GO
CREATE LOGIN Manager with password='ManagerDbo',check_policy = off;
GO--create user manager
IF USER_ID('Manager') is not nullDROP USER Manager;
GO
CREATE USER Manager FOR LOGIN Manager;
GO--create login employee
IF EXISTS(SELECT *FROM sys.sysloginsWHERE name = 'employee')
BEGINDROP LOGIN employee;
END
GO
CREATE LOGIN employee with password='employeeDbo',check_policy = off;
GO--create user employee
IF USER_ID('employee') is not nullDROP USER employee
GO
CREATE USER employee FOR LOGIN employee;
GO--create basic TABLE
IF OBJECT_ID('dbo.tb_Test_ViewPermission','u')is not nullDROP TABLE dbo.tb_Test_ViewPermission
;
GO
CREATE TABLE dbo.tb_Test_ViewPermission
(id int identity(1,1) not null primary key,name varchar(20) not null,level_no int not null,title varchar(20) null,viewByCEO char(1) not null,viewByManager char(1) not null,viewByEmployee char(1) not null,salary decimal(9,2) not null
);--data init.
INSERT INTO dbo.tb_Test_ViewPermission
SELECT 'AA',0,'CEO','Y','Y','Y',1000000.0
union all
SELECT 'BB',1,'Manager','Y','Y','Y',100000.0
union all
SELECT 'CC',2,'employee','Y','Y','Y',10000.0
;
GO
创建三个视图
表对象和数据准备完毕后,接着我们建立三个视图,分别过滤出自己所在层级及以下层级的数据。比如,CEO包含CEO、Manager和employee层级数据;Manger包含Manger和employee层级数据;employee仅包含employee层级数据。
USE Test
GO
--create views for CEO querying, CEO can get all the data
IF OBJECT_ID('dbo.v_employeeinfo_forCEO','v')is not nullDROP VIEW dbo.v_employeeinfo_forCEO
;
GO
CREATE VIEW dbo.v_employeeinfo_forCEO
AS
SELECT *
FROM dbo.tb_Test_ViewPermission WITH(NOLOCK)
WHERE level_no >= 0;
GO--create views for Manager querying, Manger can get manger group & employee group data
IF OBJECT_ID('dbo.v_employeeinfo_forManager','v')is not nullDROP VIEW dbo.v_employeeinfo_forManager
;
Go
CREATE VIEW dbo.v_employeeinfo_forManager
AS
SELECT name,level_no,title,viewByManager,viewByEmployee,salary
FROM dbo.tb_Test_ViewPermission WITH(NOLOCK)
WHERE level_no >= 1;
GO--create views for Employee querying, employee just can get employee group data
IF OBJECT_ID('dbo.v_employeeinfo_forEmployee','v')is not nullDROP VIEW dbo.v_employeeinfo_forEmployee
;
GO
CREATE VIEW dbo.v_employeeinfo_forEmployee
AS
SELECT name,level_no,title,viewByEmployee,salary
FROM dbo.tb_Test_ViewPermission WITH(NOLOCK)
WHERE level_no >= 2;
GO
权限设置
所有视图创建完毕后,接下来是最为关键的步骤,就是对视图权限的设置。基本的思路是:拿掉所有用户对于基表的权限,对于视图需要拿掉自己以下层级用户权限,然后给予视图自己层级用户的查看权限。比如:Manager层级视图dbo.v_employeeinfo_forManager需要拿掉employee的权限,授予Manager查询权限。
USE Test
GO
--====permission init.
--deny all permission to user for TABLE
DENY ALL ON dbo.tb_Test_ViewPermission TO CEO;
DENY ALL ON dbo.tb_Test_ViewPermission TO Manager;
DENY ALL ON dbo.tb_Test_ViewPermission TO employee;--deny permission for Manager & employee
DENY ALL ON dbo.v_employeeinfo_forCEO TO Manager;
DENY ALL ON dbo.v_employeeinfo_forCEO TO employee;DENY ALL ON dbo.v_employeeinfo_forManager TO employee;--Grant query permission for CEO & Manager & Employee
GRANT SELECT ON dbo.v_employeeinfo_forCEO TO CEO;GRANT SELECT ON dbo.v_employeeinfo_forManager TO Manager;GRANT SELECT ON dbo.v_employeeinfo_forEmployee TO employee;
GO
权限测试
以上所有工作准备完毕后,接下来就是最紧张的权限验证环节了,时间才是检验真理的唯一标准。
CEO权限测试
按照预期,CEO应该不能访问基表数据,会报告异常,但是可以查询CEO,manager和employee层级数据,总共三条。测试语句如下,将SSMS的结果显示切换为text模式,或者直接快捷键ctrl + t。
--CEO query test
USE test
GO--CEO cann't read data from basic table
SELECT *
FROM dbo.tb_Test_ViewPermission WITH(NOLOCK)--CEO all read the data from CEO group
SELECT CAST(CURRENT_USER AS VARCHAR(10)) AS 'Who am i',*
FROM v_employeeinfo_forCEO WITH(NOLOCK)
GO
结果显示如下,测试结果的确与预期吻合。
Manager权限测试
预期是Manger对基表没有访问权限,也没有CEO视图的访问权限,但是可以查看到Manger和普通employee的数据,也就是会返回两条数据。
--Manager query test
use test
GO--Manager cann't read data from basic table
SELECT *
FROM dbo.tb_Test_ViewPermission WITH(NOLOCK)--Manager can't read the data from CEO group
SELECT *
FROM v_employeeinfo_forCEO WITH(NOLOCK)
GO--manager can read data from manager group
SELECT CAST(CURRENT_USER AS VARCHAR(10)) AS 'Who am i',*
FROM dbo.v_employeeinfo_forManager WITH(NOLOCK)
GO
查询结果展示如下,测试结果再次与预期吻合。
Employee权限测试
预期是employee没有基表权限,没有CEO视图查看权限,也没有Manager视图查询权限,只能看到employee层级数据,也就是会返回一条数据。
--Employee query test
USE test
GO--Employee cann't read data from basic table
SELECT *
FROM dbo.tb_Test_ViewPermission WITH(NOLOCK)--Employee can't read the data from CEO group
SELECT *
FROM v_employeeinfo_forCEO WITH(NOLOCK)
GO--Employee can't read data from manager group
SELECT CAST(CURRENT_USER AS VARCHAR(10)) AS 'Who am i',*
FROM dbo.v_employeeinfo_forManager WITH(NOLOCK)
GO--Employee just can read data from employee group
SELECT CAST(CURRENT_USER AS VARCHAR(10)) AS 'Who am i',*
FROM dbo.v_employeeinfo_forEmployee WITH(NOLOCK)
GO
结果显示如下,employee层级测试结果也完全满足预期。
写在最后
从测试结果来看,SQL Server使用视图来做权限控制方法是相当的清爽和彻底满足老鸟预期的。于是菜鸟得意洋洋的来到老鸟办公室,霸气的展示了自己的解决方案和例子,老鸟觉得非常满意。
SQL Server使用视图做权限控制相关推荐
- SQL Server 关于列的权限控制
SQL Server 关于列的权限控制 原文:SQL Server 关于列的权限控制 在SQL SERVER中列权限(Column Permissions)其实真没有什么好说的,但是好多人对这个都不甚 ...
- SQL Server 2016 行级别权限控制
背景 假如我们有关键数据存储在一个表里面,比如人员表中包含员工.部门和薪水信息.只允许用户访问各自部门的信息,但是不能访问其他部门.一般我们都是在程序端实现这个功能,而在sqlserver2016以后 ...
- Microsoft Dynamics server 2015 所有的SQL server 2012 视图 介绍及功能
微软Dynamics 2015 所有的SQL server 2012 视图 介绍及功能 此文章中SQL Server 视图可以为开发者提供帮助,以下部分摘自微软CRM官方安装文件中. Microsof ...
- SQL Server索引视图
SQL Server Views are virtual tables that are used to retrieve a set of data from one or more tables. ...
- SQL Server索引视图以(物化视图)及索引视图与查询重写
SQL Server索引视图以(物化视图)及索引视图与查询重写 本文出处:http://www.cnblogs.com/wy123/p/6041122.html 经常听Oracle的同学说起来物化视图 ...
- Spring Cloud Data Flow整合Cloudfoundry UAA服务做权限控制
我最新最全的文章都在 南瓜慢说 www.pkslow.com ,欢迎大家来喝茶! 1 前言 关于Spring Cloud Data Flow这里不多介绍,有兴趣可以看下面的文章.本文主要介绍如何整合D ...
- SQL Server 数据库 视图创建
SQL Server 数据库 视图创建 视图简介: 视图可以看作定义在SQL Server上的虚拟表.视图正如其名字的含义一样,是另一种查看数据的入口. 常规视图本身并不存储实际的数据,而仅仅是由SE ...
- 前端是怎么做权限控制的?
前端是怎么做权限控制的? 第一种权限控制 比如现在有一些项目成员,有的项目成员是测试,这个项目成员登录项目的时候就可以看到"提交冒烟用例"按钮,但是其它的项目成员则不能够看到,这个 ...
- heidisql连接远程数据库_Heidisql如何连接sql server数据库并做增删改操作?
Heidisql工具是一个功能强大的数据库连接工具,功能齐全.操作简单.用heidisql很容易完成sql server数据库的建表.删除表.更新表操作等等操作.接下来小编就给大家带来Heidisql ...
最新文章
- 弹球游戏python代码含记分模式_python编写弹球游戏的实现代码
- 南宁网络推广浅谈能使文章快速收录的技巧有哪些?
- Java8 - 使用工厂方法 supplyAsync创建 CompletableFuture
- tcp底层连接过程(c语言)
- 总结缓存使用过程中的几种策略以及优缺点组合分析
- 上车时机已到--.NETCore是适应时代发展的雄鹰利剑
- NOIP模拟测试38「金·斯诺·赤」
- 机器学习速成课程 | 练习 | Google Development——编程练习:使用 TensorFlow 的起始步骤
- TensorFlow第九步CNN BP算法学习
- GBK转unicode码查询表的改进
- Bouncy Castle Crypto API c# port
- 用Python实现二叉树、二叉树非递归遍历及绘制
- 如何规避rm-rf导致的服务器删除问题
- 阿里云服务器为何价格比较贵?
- 多想和你拉手跳恰恰恰
- Linux 磁盘管理的命令
- k2677场效应管参数引脚_场效应管k790参数
- DSP28379D_双核启动简介
- 在QT中使用MySQL数据库
- R语言:企业风险分析(4)【输入建模,拟合概率分布法】
热门文章
- Hibernate随机获取指定范围内的指定条目的记录
- CMD-NET命令详解、NET命令大全(转)
- [转载]中国公历算法
- Eclipse使用时的一些小积累
- linux 提取cpio_使用rpm2cpio,cpio提取rpm包的中的特定文件
- 导入不了css,CSS不导入。
- 手机轮廓光怎么拍_想拍美秋天叶子,别犯这5个初级错误!告诉错在哪里及咋拍正确...
- MySQL非等值连接
- MySQL 高级 - 索引 - 优势和劣势
- 在项目中缓存是如何使用的?为什么要用缓存?缓存使用不当会造成什么后果?