问题引入

这天老鸟火急火燎的跑到菜鸟旁边,想必是遇到什么难题了:“现在有这么一个场景,假如有三种角色,并且存在层级关系,他们需要访问同一个数据源表,但是需要做权限控制,使得每种角色只能看到自己及以下层级的数据。比如:公司有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使用视图做权限控制相关推荐

  1. SQL Server 关于列的权限控制

    SQL Server 关于列的权限控制 原文:SQL Server 关于列的权限控制 在SQL SERVER中列权限(Column Permissions)其实真没有什么好说的,但是好多人对这个都不甚 ...

  2. SQL Server 2016 行级别权限控制

    背景 假如我们有关键数据存储在一个表里面,比如人员表中包含员工.部门和薪水信息.只允许用户访问各自部门的信息,但是不能访问其他部门.一般我们都是在程序端实现这个功能,而在sqlserver2016以后 ...

  3. Microsoft Dynamics server 2015 所有的SQL server 2012 视图 介绍及功能

    微软Dynamics 2015 所有的SQL server 2012 视图 介绍及功能 此文章中SQL Server 视图可以为开发者提供帮助,以下部分摘自微软CRM官方安装文件中. Microsof ...

  4. SQL Server索引视图

    SQL Server Views are virtual tables that are used to retrieve a set of data from one or more tables. ...

  5. SQL Server索引视图以(物化视图)及索引视图与查询重写

    SQL Server索引视图以(物化视图)及索引视图与查询重写 本文出处:http://www.cnblogs.com/wy123/p/6041122.html 经常听Oracle的同学说起来物化视图 ...

  6. Spring Cloud Data Flow整合Cloudfoundry UAA服务做权限控制

    我最新最全的文章都在 南瓜慢说 www.pkslow.com ,欢迎大家来喝茶! 1 前言 关于Spring Cloud Data Flow这里不多介绍,有兴趣可以看下面的文章.本文主要介绍如何整合D ...

  7. SQL Server 数据库 视图创建

    SQL Server 数据库 视图创建 视图简介: 视图可以看作定义在SQL Server上的虚拟表.视图正如其名字的含义一样,是另一种查看数据的入口. 常规视图本身并不存储实际的数据,而仅仅是由SE ...

  8. 前端是怎么做权限控制的?

    前端是怎么做权限控制的? 第一种权限控制 比如现在有一些项目成员,有的项目成员是测试,这个项目成员登录项目的时候就可以看到"提交冒烟用例"按钮,但是其它的项目成员则不能够看到,这个 ...

  9. heidisql连接远程数据库_Heidisql如何连接sql server数据库并做增删改操作?

    Heidisql工具是一个功能强大的数据库连接工具,功能齐全.操作简单.用heidisql很容易完成sql server数据库的建表.删除表.更新表操作等等操作.接下来小编就给大家带来Heidisql ...

最新文章

  1. 弹球游戏python代码含记分模式_python编写弹球游戏的实现代码
  2. 南宁网络推广浅谈能使文章快速收录的技巧有哪些?
  3. Java8 - 使用工厂方法 supplyAsync创建 CompletableFuture
  4. tcp底层连接过程(c语言)
  5. 总结缓存使用过程中的几种策略以及优缺点组合分析
  6. 上车时机已到--.NETCore是适应时代发展的雄鹰利剑
  7. NOIP模拟测试38「金·斯诺·赤」
  8. 机器学习速成课程 | 练习 | Google Development——编程练习:使用 TensorFlow 的起始步骤
  9. TensorFlow第九步CNN BP算法学习
  10. GBK转unicode码查询表的改进
  11. Bouncy Castle Crypto API c# port
  12. 用Python实现二叉树、二叉树非递归遍历及绘制
  13. 如何规避rm-rf导致的服务器删除问题
  14. 阿里云服务器为何价格比较贵?
  15. 多想和你拉手跳恰恰恰
  16. Linux 磁盘管理的命令
  17. k2677场效应管参数引脚_场效应管k790参数
  18. DSP28379D_双核启动简介
  19. 在QT中使用MySQL数据库
  20. R语言:企业风险分析(4)【输入建模,拟合概率分布法】

热门文章

  1. Hibernate随机获取指定范围内的指定条目的记录
  2. CMD-NET命令详解、NET命令大全(转)
  3. [转载]中国公历算法
  4. Eclipse使用时的一些小积累
  5. linux 提取cpio_使用rpm2cpio,cpio提取rpm包的中的特定文件
  6. 导入不了css,CSS不导入。
  7. 手机轮廓光怎么拍_想拍美秋天叶子,别犯这5个初级错误!告诉错在哪里及咋拍正确...
  8. MySQL非等值连接
  9. MySQL 高级 - 索引 - 优势和劣势
  10. 在项目中缓存是如何使用的?为什么要用缓存?缓存使用不当会造成什么后果?