对于SQL Server内编程对象的安全控制是今天我在思考的问题。在MSDN上找到了几篇有用的文章。

首先微软推荐了三种做法:

1)第一种做法是在SQL Server中对一个应用程序对应创建应用程序角色。做法是在客户端开启连接请求到SQL Server服务器的时候指定ApplicationRole名字和密码。这种做法需要做的工作少而且后期维护的成本低,但是前提是比较简单而且密码是暴露在客户端的。它无法完成在存储过程中的不同代码片段进行权限控制。

2)第二种做法是使用EXECUTE AS表达式加上WITH COOKIE字句来针对某个代码块切换当前用户执行上下文到某个权限更高/低的用户的执行上下文,然后通过REVERT表达式切换回caller。它的前提是要授权某个用户对于另外一个用户具有IMPERSONATE的权限。这种做法得出好处是对安全控制更加细化,细化到当前过程中的某个代码片段的身份。而缺点是加大了编码的复杂性,需要开发人员在开发时的配合。

3)第三种方法是对存储过程/函数/触发器进行证书签名,这样当存储被调用的时候,SQL Server就会把caller的权限和证书签名的用户的权限做一个合集,从而不需要切换执行上下文。当中需要创建一个证书以及一个和证书相关联的数据库用户(与login无关联),然后对数据库用户授权数据库对象的访问权限。而存储过程的签名(非对称)其实就是对存储过程代码产生hash值,然后用生成的私钥进行加密。在每次执行的时候用公钥解压得到存储过程的hash值,然后和现有存储过程的hash值进行比对,如果不一致就说明上次加密后存储过程本身受到修改,这个时候会报错。每次修改存储过程需要对存储过程重新签名。

说了这么多,做法有多种:

1)以前的项目经验是将Database Role与Windows Active Directory的Security Group结合来控制Windows登陆用户对于数据库实体对象和编程对象的访问权限控制。但是这种做法的弊端。管理成本有点高。需要得到AD的某个组织单位的管理权限,可以添加修改AD的用户。小项目还行。

2)第二种做法之前写过文章讲REVERT。这种做法在某些场景是很好用的。对权限的控制是最到位的。只是要对开发人员的培训。在大型项目中挺不错。把所有的权限控制都放到存储过程中控制。这样我们可以只给应用程序层最小的权限。这样最大程度避免了权限泄露(overflow)的可能。是我觉得三者中最不错的解决方案。有一点需要说明一下,我一直以为这种EXECUTE AS USER的做法其实是复制了login的权限。其实不是。这里是站在database层面的。于是我做了一个测试,login1对DB1和DB2中各自的A表都没有写入权限,login2对DB1和DB2中各自的A表都有写入权限。现在login2各自映射到DB1和DB2中的user1。假设在DB1中创建一个存储过程sp1,EXECUTE AS USER = 'user1'对DB1和DB2中个各自的A表插入一行记录(对DB2库中的A表插入数据采用[db].[schema].[table]这种引用方法)。我设想是既然我impersonate了DB1中user1的身份,那么我按道理来说,两个数据库的user1都是代表了login1,其实我也相当于impersonate了DB2中user1的身份,那么即便说存储过程是存在DB1中,我对DB2中表进行数据插入也是没问题的。事实相反。那么仔细来思考这个问题,其实我这么想是错的。如果真是这样,那必然会存储巨大的安全隐患。不可能说某个login对A数据库没有访问或者对象的访问权限,而你可以通过impersonate某个库中的用户然后顺带获得这个用户所映射的login的权限去其他数据库进行数据库对象操作。这其实是个非常危险的想法。这个在EXECUTE AS (Transact-SQL)中已经做了说明。这个这里不做demo了,前面的SQL Server ->> EXECUTE AS LOGIN/USER和Revert表达式已经讲了。

3)第三种做法是针对整个存储过程范围而言,而有其他另一种做法是通过在创建或者修改存储过程的时候添加WITH EXECUTE AS 'user'来针对整个存储过程进行上下文切换。前者相比较后者的优势是不需要切换执行上下文,这样我们可以追踪真实的caller,对于audit是很有帮助的,保留原始/真实身份信息。还有一点是它是以一种权限合并的方式合并了caller和证书用户的权限。而缺点是因为对存储过程进行了签名,每次修改都需要重新签名。

4)第一种做法我没试过,不过从它自身的缺点来看,应该没有后两者好。

参考:

Creating Application Roles in SQL Server

Customizing Permissions with Impersonation in SQL Server

Signing Stored Procedures in SQL Server

Tutorial: Signing Stored Procedures with a Certificate

SQL Server ->> Database Promgramming Object Security Control(数据库编程对象安全控制)的更多相关文章

  1. How to Kill All Processes That Have Open Connection in a SQL Server Database[关闭数据库链接 最佳方法] -摘自网络

    SQL Server database administrators may frequently need in especially development and test environmen ...

  2. SQL Server 游标运用:查看所有数据库所有表大小信息(Sizes of All Tables in All Database)

    原文:SQL Server 游标运用:查看所有数据库所有表大小信息(Sizes of All Tables in All Database) 一.本文所涉及的内容(Contents) 本文所涉及的内容 ...

  3. SQL Server 游标运用:查看一个数据库所有表大小信息(Sizes of All Tables in a Database)

    原文:SQL Server 游标运用:查看一个数据库所有表大小信息(Sizes of All Tables in a Database) 一.本文所涉及的内容(Contents) 本文所涉及的内容(C ...

  4. P6 Professional Installation and Configuration Guide (Microsoft SQL Server Database) 16 R1

    P6 Professional Installation and Configuration Guide (Microsoft SQL Server Database) 16 R1       May ...

  5. SQL Server database mail问题诊断一例

    产品环境sql server database的mail发不出邮件,影响客户的业务,在数据库中进行诊断 诊断sql: EXEC msdb.dbo.sp_send_dbmail @profile_nam ...

  6. Create a SQL Server Database on a network shared drive

    (原文地址:http://blogs.msdn.com/b/varund/archive/2010/09/02/create-a-sql-server-database-on-a-network-sh ...

  7. 使用SQL Server Management Studio 创建作业备份数据库

    在项目中,经常需要备份数据库,如果能做到只需点个按钮(“开始备份数据库”按钮),然后什么都不管,数据库就自动备份好了,或者服务器上的数据库隔一段时间自动备份一次,那该多好啊. Sql server 的 ...

  8. SQL Server如何附加只有mdf的数据库文件

    有时候SQL Server意外断电会导致SQL Server的ldf日志文件丢失或者损坏,这个时候你如果直接附加mdf文件到SQL Server会失败,这里提供一个方法可以还原只有mdf的数据库文件, ...

  9. SQL Server ->> 重新创建Assembly和自动重建相关的数据库编程对象(存储过程,函数和触发器)

    在SQL Server中,一旦一个Assembly被其他的数据库编程对象(存储过程,函数和触发器)引用了,这个Assembly就不能被删除.但是问题是,在SQL Server要更新一个Assembly ...

随机推荐

  1. 服务端模拟http服务请求客户端

    try { InputStream in = req.getInputStream(); int i = -1; ByteArrayOutputStream out = new ByteArrayOu ...

  2. numpy多维矩阵,取出第一行或者第一列,方法和df一样

    # 定义一个多维矩阵 arr = np.array([[1,2,3], [4,5,6], [7,8,9]]) # 取出第一行 arr[0,:] # 取出第一列 arr[:,0]

  3. 更改kindeditor编辑器,改用支持h5的video标签替换原有embed标签

    kindeditor是一款不错的可视化编辑器,不过最近几年似乎没在更新,现在h5趋于主流,正好有个业务需要编辑器支持mp4视频的播放,考虑到现在h5中的video标签的强大,于是决定将原来系统中的em ...

  4. Java学习之路(四):面向对象

    Java中的面向对象 概念:面向对象的原本的意思是“”万物皆对象“” 面向对象思想的特点: 是一种更符合我们思想习惯的思想,将复杂的事情简单化 使我们角色发生了转换,将我们从执行者变成了指挥者 面向对 ...

  5. Python数据类型(列表)

    文章内容参考了教程:http://www.runoob.com/python/python-basic-syntax.html#commentform Python 列表(List) 序列是Pytho ...

  6. spring异常被吞的一种情形

    你是否遇到过下面的情况,控制台无限的输出下面的日志: Logging initialized using ‘class org.apache.ibatis.logging.log4j.Log4jImp ...

  7. javascript array类型用法

    javascript高级编程-Array引用类型用法总结  2016-09-17   |    357 引用类型-Array类型 引用类型是一种数据结构,用于将数据和功能联系起来. 创建对象的方式: ...

  8. HDU 5691 ——Sitting in Line——————【状压动规】

    Sitting in Line Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Other ...

  9. Java并发编程系列之二十八:CompletionService

    CompletionService简介 CompletionService与ExecutorService类似都可以用来执行线程池的任务,ExecutorService继承了Executor接口,而C ...

  10. Jmeter进行性能测试时多台负载机的配置方法

    参考:https://blog.csdn.net/russ44/article/details/54729461 Jmeter进行性能测试时多台负载机的配置方法 Jmeter 是java 应用,对于C ...