Rovan

      一个犁牛半块田,收也凭天,荒也凭天, 清茶淡饭饱三餐,早也香甜,晚也香甜, 布衣得暖胜丝绵,长也可穿,短也可穿, 草舍茅屋有几间,行也安然,待也安然, 雨过天青驾小船,鱼在一边,酒在一边, 夜归儿女话灯前,今也有言,古也有言, 日上三竿我独眠,请是神仙,我是神仙.

首页 新随笔 联系 订阅 管理
异常管理

  当 .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 要求此方法的调用程序
// 具有一个名为“MyUser”的身份标识,并且属于角色“Administrator”。
[PrincipalPermissionAttribute(SecurityAction.Demand,
Name="MyUser", Role="Administrator")]
public void DeleteCustomer(string customerID)
{
// 在此处删除客户代码
}
}

  以下代码显示了如何创建具有所需身份标识和角色的 Principal 对象,以便对 CustomerDALC 对象调用 DeleteCustomer 方法:

using System;
using System.Security.Principal;
using System.Threading;

public class MainClass
{
public static int Main(string[] args)
{
Console.Write("用户名:");
string UserName = Console.ReadLine();

Console.Write("密码:");
string Password = Console.ReadLine();

if (Password == "password" && UserName == "MyUser")
{
// 创建一个名为“MyUser”的通用身份标识
GenericIdentity MyIdentity = new GenericIdentity("MyUser");

// 创建角色
String[] MyString = {"Administrator", "User"};

// 创建一个通用当事人
GenericPrincipal MyPrincipal = new GenericPrincipal(MyIdentity,
MyString);

// 设置此线程的当前当事人,以用于基于角色的安全性
Thread.CurrentPrincipal = MyPrincipal;
}

// 创建一个 CustomerDALC 对象,并尝试调用它的 DeleteCustomer 方法。
// 仅在当前当事人的身份标识和角色合格时这一步骤才能成功。
CustomerDALC c = new CustomerDALC();
c.DeleteCustomer("VINET");
}
}

  Windows 身份验证   

  理想情况下,在连接到数据库时应使用 Windows 身份验证而不是 SQL Server 身份验证。然而,应使用服务帐户并避免模拟连接到数据库,因为它会妨碍连接池。连接池需要相同的连接字符串;如果尝试使用不同的连接字符串打开数据库,就会创建单独的连接池,而这将限制可缩放性。

  安全通信建议

  要实现调用应用程序与数据访问逻辑组件之间的安全通信,请考虑以下建议:

  • 如果数据访问逻辑组件是通过各种层的线路调用的,并且信息交换包含需要保护的机密信息,则应使用分布式组件对象模型 (DCOM)、安全套接字层 (SSL)、安全 Internet 协议 (IPSec) 等安全通信技术。
  • 如果数据是加密存储在数据库中,则通常由数据访问逻辑组件负责数据的加密与解密。如果信息暴露会导致巨大损害,则必须考虑保护与数据访问逻辑组件进行通信的通道。
posted on 2006-07-06 16:58  Ruxuan  阅读(197)  评论(0)    收藏  举报