对于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. Python练习 | WebServer

    #-*- coding:utf-8 -*- import sys, os from http.server import BaseHTTPRequestHandler, HTTPServer #--- ...

  2. PHP面向对象的基本思路

    第一步:识别对象 ——任何实体都可以被识别为一个对象 第二步:识别对象的属性 ——对象里面存储的数据被识别为属性 ——对于不同的业务逻辑,关注的数据不同,独享里面存储的属性也不同 第三步:识别对象的行 ...

  3. git笔记(三)

    详细输出日志 git log --pretty=raw 查看id类型 git cat-file -t fe4c git cat-file -t b36bf6 git  cat-file  -t b08 ...

  4. CentOS下输入输出重定向

    nux重定向是指修改原来默认的一些东西,对原来系统命令的默认执行方式进行改变,比如说简单的我不想看到在显示器的输出而是希望输出到某一文件中就可以通过Linux重定向来进行这项工作. Linux默认输入 ...

  5. rabbit工作队列模式

    工作队列比简单队列在消费者这边多了一个方法. channel.basicQos(1);公平队列消费(参数设置为1,表示消费者消费完一条才会去接受再次发来的消息) 生产者: package com.kf ...

  6. Hibernate 学习(二)

    一.Hibernate 核心 API 1.Configuration 对象(配置) 配置对象是你在任何 Hibernate 应用程序中创造的第一个 Hibernate 对象,并且经常只在应用程序初始化 ...

  7. 任意表格(table)实现拖动列(column)改变列大小

    直接上代码吧,原理可以看我上一篇博文.本实现基于jquery,完美实现拖动改变表格的列大小功能,只需将代码放置在你页面的底部即可(jquery必须先引入). $(function () { var i ...

  8. 解决JVM内存溢出问题

    今天遇到了一个问题,当我在增加配置文件(*.xml)内容的时候,重新启动tomcat6时,控制台报错:java.lang.StackOverflowError: 即,栈溢出错误. 内存溢出,即程序运行 ...

  9. pycharm下 os.system os.popen执行命令返回有中文乱码

    原文 settings:

  10. JS读取粘贴板内容

    1.1     监听onpaste事件 1.1.1 定义和用法 npaste 事件在用户向元素中粘贴文本时触发. 注意: 虽然使用的 HTML 元素都支持 onpaste 事件,但实际上并非支持所有元 ...