SQL Server 团队所推荐的新方法是将关键字 AttachDBFilename 添加到连接字符串。如果一直用于 Web 应用程序,对于典型 SQL Server 客户端/服务器前端应用程序而言,这是不常用而且是极少使用的方法。对于说明 SQL Sever 实例的任意连接字符串,您必须按名称(或 IP 地址)指向服务器并提供一个实例名。此外,当使用 AttachDBFilename 关键字指向连接字符串中的文件名时,ADO.NET(或 ADO)会通知目标 SQL Server 实例,您希望将引用的文件“附加”到服务器 — 这样,在打开连接的过程中会将该数据库注册在 SQL Server Master 数据库中。
在附加数据库后,当您引用数据库时,从此时起,该服务器访问引用的文件 (.MDF) 及其附带日志文件 (.LDF)。因为此处有一个 catch 语句,请务必小心。您必须 在连接字符串中指定 Database 关键字。如果不指定,该服务器则无法确定这个新附加的数据库。代码列表 1 显示了被配置为附加并打开一个 .MDF 文件的 ADO.NET Sqlclient.SqlConnection 对象的示例。
代码列表 1. 使用 AttachDBFilename 关键字连接到 SQL Server .MDF 文件。
Try
cn = New SqlConnection("Data Source=.\SQLExpress;" _
& "Integrated Security=True;Database=Biblio;" _
& "Timeout=60;" _
& "Application Name=SQLExpress Test;" _
& "AttachDBFilename=" & strFn)
da = New SqlDataAdapter("SELECT AU_ID, Author, Year_Born from authors", cn)
ds = New DataSet
da.Fill(ds)
DataGridView1.DataSource = ds.Tables(0)
Catch ex As Exception
MsgBox(ex.ToString)
End Try
提示 将新数据库附加到 Master 的过程比简单地打开它要花费更多的时间。确保设置连接字符串 Timeout 关键字,以考虑该增加的时间。
管理附加的 .MDF 数据库文件
尽管打开连接的过程会附加一个数据库,但是当应用程序关闭该连接时,数据库并没有分离。一旦附加,它会永久性地安装在 SQL Server 实例中。这意味着在应用程序结束后,数据库本身对任何应用程序都是可视的,且带有足够的权限。它还表示您需要负责在带有其他应用程序文件的相同目录中维护数据库文件。由于在 SQL Server 运行时,文件受到 Windows 的保护,所以在没有首先从数据库分离时,它不应该被“更新的”版本所覆盖。当然,分离并不困难。您可以从 SQLCMD 中使用以下命令,或使用 SQL Server 2005 GUI 管理工具。另一种方法是使用当使用该数据库的所有应用程序结束时自动关闭数据库文件的 AutoClose 选项。
EXEC sp_detach_db ''MyDb''
GO
请记住要将数据库文件保存在本地硬盘上,而不是保存在共享的网络服务器上。强制 SQL Server 执行通过线缆的物理 I/O(即使它支持该操作)是非常危险的,并且它确实会降低您的性能。
与 JET 数据库不同,备份 SQL Server 数据库文件(可能有若干个文件)非常简单,但是备份过程还涉及了通过 OSQL(其中一个工具)或 SMO 向 SQL Server 发送 T-SQL 命令。数据库可以在任何时间进行备份,可以带有任何数量的登录(和活动)用户。
直接连接到名为 SQL Server Express 的数据库
连接到名为 SQL Server Express 实例(或任意 SQL Server 实例)上的命名数据库的更典型方法是,简单地在实例名后写出计算机名,如代码列表 2 所示。这种方法假设作为目标的 Database 已经注册了 SQL Server Master 数据库。
代码列表 2. 使用对已注册的 SQL Server 数据库的“直接”访问。
cn = New SqlConnection("Data Source=.\SQLExpress;" _
& "Integrated Security=True;Database=Biblio;" _
& "Timeout=60;" _
& "Application Name=SQLExpress Test;" _
& "AttachDBFilename=" & strFn)
注 SQL Server Express 仍然支持连接字符串的“(local)”或“.”表示法来指代 SQL Server 的“默认”实例,但前提是只有您按照我前面所述安装了“默认”实例。我并不建议使用这种方法,因为 SQL Server Express 服务器可能不是服务器上的原始“默认”实例。
使用备用的实例名
您不必使用默认的“SQLEXPRESS”实例名来安装 SQL Server Express。我可以想象出几种情况来说明使用默认实例名并不是很好的解决方案。在这种情况下,您需要使用安装过程中的“高级配置”选项,以选择另一个实例名并在连接字符串中使用这个实例名。这种方法的问题在于,如果应用程序安装实用工具不知道安装在目标服务器上的数据库名称,您的名称可能会与现有名称发生冲突 — 正像在用户系统上安装 SQL Server 的某个其他应用程序可能会与您选择的名称发生冲突一样。这就解释了为什么 SQLEXPRESS 的公用实例名是如此重要的一项创新。
使用别名
从应用程序连接到“公用”服务器名的另一种方法是使用别名。也就是说,您可以使用 SQL 计算机管理器来为 SQL Server 实例指定一个别名(如图 5 所示)。在此例中,我创建了别名“George”,我可以将其用于我的连接字符串中。如果基本服务器发生变化(例如,当我从测试服务器更改为生产服务器时),我只要更改别名,该应用程序就会重定向到正确的服务器。
利用 Windows 身份验证模式管理集成安全性
当您的连接字符串包含关键字 Integrated Security=SSPI 时,ADO.NET(或您所使用的数据访问接口)则使用 Windows 身份验证模式。在幕后,这种模式使用 NTLM (NT LAN Man) Windows NT 质询/响应身份验证协议来验证使用加密的帐户凭据,以便保护传输过程中的密码以防止“刺探者”以离线状态攫取您的凭据。每次打开(或重新打开)连接时,用户凭据会根据域控制器 (Active Directory) 数据库重新进行验证。Microsoft 建议对大多数应用程序使用 Windows 身份验证模式。
注有关安全性支持提供程序 (SSP) 软件包(如 NTLM 和 Kerberos)的详细信息,请参阅 Platform SDK 中的 SSP Packages Provided by Microsoft。
当然,我所编写的用于验证这段代码的测试应用程序可以正常工作(该代码显示在代码列表 1 中)。因为我是以管理员身份登录的,所以我的 Windows 帐户被授予了 SQL Server 上的系统管理员权限。这就是当使用 SQL Server Express 时,为什么不需要使用 SA 帐户或者不需要知道 SA 密码的原因所在。然而,我的确希望最终用户不被授予管理员帐户。当任何人登录到 Windows 域时,域管理员会确定授予他们的权限。该信息存储在 Active Directory 中。这些权限不会传递到 SQL Server,除非您特别地授予这些权限。这意味着(默认情况下)不会 为非管理员授予到服务器或其内容的权限,并且您将需要设置用户、组和角色以管理数据库及其内容。执行该操作的机制在一段时间以来都没有改变,在 SQL Server Books Online 中有对它们的详细说明。有关 SQL Server 安全性非常好的操作的详细信息,请访问 TechNet。
从基本上讲,您需要建立并配置四层安全性。
1.Windows 域帐户:系统管理员需要建立域帐户,包括登录名和(强)密码 — 用户“凭据”。该帐户(默认情况下)是“Domain Users”组的成员。管理员可以建立其他组并根据需要将用户分配到这些组。我通常建立用户的“类”,它按照用户在办公室中被分配的工作角色的类型对其进行分类。例如,我将建立“Accounting Admin1”和“Accounting Admin Lead”组,并将特定的 Windows 域帐户添加到这些组。可以分配给单个 Windows 用户多个角色。
2.工作站和用户的物理安全性。如果在用户离开时,工作站保留为登录状态,或者用户允许其他人使用他们的 Windows 帐户凭据,那么您的安全性已经被洞穿。这一层通常被忽略。这就解释了为什么当用户没有实际出现时 Microsoft 使用密钥访问系统来防止对系统的访问。
3.SQL Server 登录:这是在 SQL Server 上建立的帐户,用于屏蔽连接到 SQL Server 的尝试。您向该列表中添加的每个帐户,都会减弱保护数据的服务器能力,因为它允许额外的 Windows 用户获得对该服务器的访问。当使用集成安全性(我们建议这么做)时,您仍然需要在 SQL Server 上建立一个登录帐户,以允许特定用户或 Windows 域组(例如 Domain Users)对目标数据库进行访问。授予每个登录帐户对一个或多个数据库的访问权限,并且如果初始目录 (Database) 关键字没有在连接字符串中使用,则分配一个所引用的默认数据库。
4.数据库用户:保护的最后一层是在数据库本身中进行管理的。在这种情况下,您需要建立一个或多个数据库用户,为这些用户授予对特定表格、视图、函数和存储过程的访问权限。如果需要,您甚至可以授予对特定列的访问权限。
在任何 SQL Server 数据库上管理安全性帐户的一个方法就是使用 SQLCMD。但是,除非您是数据库管理员 (DBA) 并且具有 T-SQL 的丰富经验,否则这可能有一点令人畏缩。幸运的是,您可以使用 SQL Server 2005 Management Studio(与 SQL 企业管理器等价)来创建数据库用户、组或角色。该工具没有包括在 SQL Server Express 中,因此您需要使用 Microsoft 提供的标准版或开发人员版的工具或使用第三方的一个工具。在创建这些角色后,您可以使用 SQL 工具将这些 T-SQL 命令导出到一个脚本文件。
使用混合模式的安全性
混合模式身份验证是使用 Windows 集成安全性的一个备选方法。在这种情况下,连接字符串 UID 和 PWD 关键字会根据 SQL Server 登录名和密码进行验证。由于这种技术绕过了 Windows 身份验证,它被认为是不太安全的。要使用这种安全性模式(并忽略我们的建议),您需要在安装过程中启用这种混合模式安全性。为此,当使用安装批处理文件时,您可以将 SECURITYMODE 命令参数设置为“SQL”。该选项还可用于 SQL Server Express 交互式安装程序和 SQL Server Express Manager (XM),其预览版本应该很快就可用了。
SQL Server 安全性常规指南
无论它是每小时百万次点击量的企业服务器还是每千年百万次点击量的小型办公系统,在任意系统上违反安全,都可能意味着公司的崩溃 — 或者丢掉您的工作。由于 SQL Server Express 系统假设应用程序扮演很多安全性角色,需要对其进行准备才能管理 SQL Server 登录、执行周期性维护(例如数据和日志备份)、将备份存储移动到系统外(最好是现场外)以及适于数据库使用的其他维护任务。应用程序还需要采取措施来监视服务器日志的运行状况,并且在遇到问题时对其进报告。
不熟悉 SQL Server 的开发人员通常会忽略一个维护安全性的更基本的方法,例如 SQL Server 具有将对象保护到列的能力。在大多数关键的办公系统中,DBA(如果有)会直接将访问权限限制到基表。此后,DBA 为重点访问数据库的人建立特定的用户和角色帐户,根据专用视图、存储过程和函数启用适当的权限。这样,如果用户凭据被盗,可以访问数据的唯一方法就是通过这些非常简单地限制的机制。
小结
本文介绍了 SQL Server 2005 的新改进的版本,也称为 Express Edition。我讨论了使 SQL Server Express 易于使用并易于保护的差异,并讨论了几个安全性问题,涉及了保护数据、保护服务器以及保护物理系统。我希望这篇概述能够促使您将现有的 JET 应用程序迁移到更安全稳定的 SQL Server 2005 Express Edition 中。