在Windows Communication Foundation (WCF)中,为了阻止服务的实现细节从服务的安全边界泄露,未知的异常不应该被发送至客服端。在WCF配置中将<serviceDebug>配置节的includeExceptionDetailInFaults属性的值显式设置为false后(或干脆不设置,因为False是默认值),即可达到此目的。
备注: |
includeExceptionDetailInFaults配置只用于未知的或未被处理的异常。对已知的异常(标有FaultContract特性的operation在其实现中抛出的FaultException<knownFault>类型的异常)无效。 |
“异常保护”用于当一个异常被抛出时阻止其服务的内部实现信息的泄露。以下是使用“异常保护”的理由:
- 异常的细节中所包含的信息可能会被黑客利用来挖掘系统的资源。
- 一些预期的异常信息需要被返回给客户端。
- 在一个Web服务中发生的异常应该被记录下来,以帮助故障诊断。
只有那些被处理过的或在设计中被设定为安全的异常才应该被返回至客户端。在设计中被设定为安全的异常在其message中不包含一些敏感信息,也不包含具体的stack trace,因为它们可能会泄露Web服务内部的实现信息。你应该使用“异常保护”模式,将不安全的异常处理成安全的异常。
异常处理应用块(Exception Handling Application Block)包含在WCF服务边界上对“异常保护”的支持。这包含以下部分:
- “异常保护特性(Exception Shielding Attribute)”,用来将一个在异常处理应用块中配置的命名的异常处理策略关联至一个WCF服务操作(operation)。
- “错误契约异常处理器(Fault Contract Exception Handler)”,用来将一个异常转化为一个指定类型的错误契约(Fault Contract)并映射相应的属性。
使用异常保护特性(Exception Shielding Attribute)
为一个WCF服务中增加异常保护功能
- 加入以下程序集:
- Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.dll
- Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.WCF.dll
- Microsoft.Practices.EnterpriseLibrary.Common.dll
- Microsoft.Practices.Unity.dll
- Microsoft.Practices.Unity.Interception.dll
- Microsoft.Practices.ServiceLocation.dll
- 使用using (C#) 或 Imports (Visual Basic) 语句引入命名空间Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.WCF
- 为服务实现类或服务契约接口增加“ExceptionShielding”特性,同时指定异常处理策略名作为其构造方法的参数。若不指定异常处理策略名,或其指定的策略未在配置中定义,则默认查找名字为“WCF Exception Shielding”的策略进行处理。
- 在服务的Web.config文件中增加异常处理应用块的配置节,然后在其中定义所需要的异常处理策略与异常处理器。“错误契约异常处理器”(在下面的章节中有描述)用来将异常映射至为操作契约(operation contract)定义的错误契约。
- 在服务的客户端实现异常处理逻辑,以捕获服务可能抛出的异常并将它们发送至异常处理应用块。
以下的代码指定了一个服务契约,其中包括一个可能抛出名为SystemUnavailableFault 错误契约的GetQuote操作(operation)。ExceptionShielding特性被应用至服务实现类(QuoteService类),通过构造方法的参数指定当异常发生时执行名为QuoteServicePolicy的异常处理策略。
|
|
[ServiceContract] public interface IQuoteService { [OperationContract] [FaultContract(typeof(FaultContracts.SystemUnavailableFault))] QuoteResponseType GetQuote(QuoteRequestType request); }
[ExceptionShielding("QuoteServicePolicy")] public class QuoteService : IQuoteService { public QuoteResponseType GetQuote(QuoteRequestType request) { // Method code here... } } |
|
|
|
|
使用错误契约异常处理器
在WCF应用程序中使用异常处理应用块进行异常保护时,你可以使用错误契约异常处理器将一个运行时异常转换为一个合适的错误契约类型。此异常处理器也让你能够将原始异常中的属性与处理实例的ID映射至错误契约中的属性。
为了使用错误契约异常处理器
- 创建一个异常处理策略,其中包含对你的应用程序来说合适的异常类型。
- 配置异常类型,将ThrowNewException指定为其处理后行为(post-handling action)。这意味着处理块将在整条处理器链运行完毕后抛出新的异常(包装了原始异常)。
- 为指定的异常类型增加一个新的错误契约异常处理器。
- 配置错误契约异常处理器:
- 指定应该要被返回至客户端的错误契约类型。
- 增加要被返回至客户端的错误契约使用的异常信息。
- 此步可选。配置属性从原始异常至目标错误契约的映射方式。在处理器配置的Property Mappings节中映射每一个你想映射的属性。映射的“Name”属性用于指定错误契约中的属性名,“Source”属性用于指定原始异常。你也可能使用{HandlingInstanceId}以将当前的处理实例的ID指定至错误契约属性。
错误契约异常处理器将自动映射原始异常中所有名字匹配且类型兼容的属性至目标错误异常。若你不想这样,你可以指定一条映射,将其“Name”属性值设为目标错误契约的属性名,并将其“Source”属性值设为空字符串。