当 .NET 应用程序出现错误时,通常的建议是发出异常而不是从方法返回错误值。这一建议暗示了您编写数据访问逻辑组件和业务实体组件的方式。异常大体上有两种:
- 技术异常,它包括:
- ADO.NET
- 数据库连接
- 资源(如数据库、网络共享、消息队列等)不可用
- 业务逻辑异常,它包括:
- 验证错误
- 实现业务逻辑的存储过程中的错误
数据访问逻辑组件应该传播异常,并且仅在能够使客户端对异常的管理更加容易时才包装异常类型。将异常包装为两种主要异常类型(技术异常和业务异常)有利于各种可能的调用程序的异常处理结构和异常发布逻辑。
您的应用程序应当发布异常信息。可以将技术异常发布到一个由系统管理员或 Windows 管理规范 (WMI) 监视工具(如 Microsoft Operations Manager)监视的日志中;将业务异常发布到一个特定的应用程序日志中。通常,应允许从数据访问逻辑组件传播异常并允许由调用程序发布异常,以便您了解异常的整个环境。
以下示例说明了这些建议:
| public class CustomerDALC { public void UpdateCustomer(Dataset aCustomer) { try { // 更新数据库中的客户... } catch (SqlException se) { // 捕获并包装异常,然后重新发出 throw new DataAccessException("数据库不可用", se); } finally { // 清除代码 } } } |
在业务实体组件中管理异常的建议
业务实体组件应当向调用程序传播异常。在业务实体组件执行验证或者当调用程序试图执行某一操作而未提供该操作所需的数据时,业务实体组件也可以产生异常。
以下示例显示了业务实体组件如何产生异常。在此示例中,如果没有提供客户的名字,Update 方法将发出一个异常:
| public class CustomerEntity { public void Update() { // 检查用户已提供了所需数据。这里是客户 // 的名字 if (FirstName == "" ) { // 发出一个已定义的新的应用程序异常 throw new MyArgumentException("您必须提供名字。"); } ... } } |
授权与安全性
本节说明如何将安全性应用于数据访问逻辑组件和业务实体组件。.NET 公共语言运行库使用权限对象实现其对托管代码的强制限制机制。权限对象有三种,各自具有特定的用途:
- 代码访问安全性。这些权限对象用于防止未经授权使用资源和操作。
- 身份标识。这些权限对象指定运行程序集时所必需的身份标识特征。
- 基于角色的安全性。这些权限对象提供了一个机制,用于判断用户(或用户的代理人)是否具有特定身份标识,或者是否是指定角色的成员。PrincipalPermission 对象是唯一基于角色的安全性权限对象。
托管代码可以使用 Principal 对象(包含对 Identity 对象的引用)来判断当事人的身份标识或角色。把 Identity 对象和 Principal 对象与用户、组帐户等大家所熟悉的概念比较可能会更容易理解。在 .NET Framework 中,Identity 对象表示用户,而角色表示成员身份和安全性环境。Principal 对象封装了 Identity 对象和角色。.NET Framework 中的应用程序根据 Principal 对象的身份标识或角色成员身份(后者更常见)授予 Principal 对象权限。
数据访问逻辑组件中的安全性建议数据访问逻辑组件的设计目的是供其他应用程序组件使用,它也是您的应用程序代码中在调用程序可以访问数据之前实现安全性的最后一个地方。
通常,数据访问逻辑组件可以依赖于由调用程序设置的安全性环境。然而,有些情况下数据访问逻辑组件必须执行自己的授权检查,以确定是否允许当事人执行所请求的操作。授权在身份验证后进行,并使用当事人身份标识与角色等有关信息来确定该当事人可以访问的资源。
在以下情况下,应在数据访问逻辑组件层次上执行授权检查:
- 需要与不完全信任的业务过程开发人员共享数据访问逻辑组件
- 需要保护对数据存储提供的强大功能的访问
在定义了 Identity 对象和 Principal 对象后,可以用三种方式执行基于角色的安全性检查:
- 使用 PrincipalPermission 对象执行强制性安全性检查。
- 使用 PrincipalPermissionAttribute 属性执行说明性安全性检查。
- 使用 Principal 对象中的属性和 IsInRole 方法执行显式安全性检查。
以下代码示例显示了如何使用 PrincipalPermissionAttribute 为数据访问逻辑组件类中的方法指定基于角色的声明性安全性检查:
| using System; using System.Security.Permissions; public class CustomerDALC public CustomerDALC() // 使用 PrincipalPermissionAttribute 要求此方法的调用程序 |
以下代码显示了如何创建具有所需身份标识和角色的 Principal 对象,以便对 CustomerDALC 对象调用 DeleteCustomer 方法:
|
using System; public class MainClass Console.Write("密码:"); if (Password == "password" && UserName == "MyUser") // 创建角色 // 创建一个通用当事人 // 创建一个 CustomerDALC 对象,并尝试调用它的 DeleteCustomer 方法。 |
理想情况下,在连接到数据库时应使用 Windows 身份验证而不是 SQL Server 身份验证。然而,应使用服务帐户并避免模拟连接到数据库,因为它会妨碍连接池。连接池需要相同的连接字符串;如果尝试使用不同的连接字符串打开数据库,就会创建单独的连接池,而这将限制可缩放性。
安全通信建议要实现调用应用程序与数据访问逻辑组件之间的安全通信,请考虑以下建议:
- 如果数据访问逻辑组件是通过各种层的线路调用的,并且信息交换包含需要保护的机密信息,则应使用分布式组件对象模型 (DCOM)、安全套接字层 (SSL)、安全 Internet 协议 (IPSec) 等安全通信技术。
- 如果数据是加密存储在数据库中,则通常由数据访问逻辑组件负责数据的加密与解密。如果信息暴露会导致巨大损害,则必须考虑保护与数据访问逻辑组件进行通信的通道。
浙公网安备 33010602011771号