我正在编写一个带有一些身份验证和自定义错误处理程序的 WCF 服务。但是,我IErrorHandler
遇到了这个问题:当身份验证引发异常时,我的实现没有受到影响,但在其他异常情况下运行得很好。
身份验证是否在IErrorHandler
构建之前运行?我是在吠叫错误的树,试图让它捕捉这些错误吗?
是的,我已经尝试(并且正在)FaultException
在我的身份验证中添加 a,而不是SecurityTokenException
.
我正在编写一个带有一些身份验证和自定义错误处理程序的 WCF 服务。但是,我IErrorHandler
遇到了这个问题:当身份验证引发异常时,我的实现没有受到影响,但在其他异常情况下运行得很好。
身份验证是否在IErrorHandler
构建之前运行?我是在吠叫错误的树,试图让它捕捉这些错误吗?
是的,我已经尝试(并且正在)FaultException
在我的身份验证中添加 a,而不是SecurityTokenException
.
所以首先要确保您的自定义错误处理程序也实现了 IServiceBehavior。IServiceBehavior 要求您实现几个其他方法,但重要的是“ApplyDispatchBehavior”,您必须在其中将 ErrorHandler 添加到通道调度程序。
C#
public class CustomErrorHandler: IServiceBehavior, IErrorHandler
{
public bool HandleError(Exception error)
{
//Return True here if you want the service to continue on as if
// the error was handled
return true;
}
public void ProvideFault(Exception error,
MessageVersion version,
ref Message fault)
{
FaultException fe = new FaultException(
new FaultReason(error.Message),
new FaultCode("Service Error"));
MessageFault mf = fe.CreateMessageFault();
fault = Message.CreateMessage(version, mf, fe.Action);
}
public void ApplyDispatchBehavior(ServiceDescription serviceDescription,
ServiceHostBase serviceHostBase)
{
IErrorHandler eh = new CustomErrorHandler();
foreach (ChannelDsipatcherBase cdb in serviceHostBase.ChannelDispatchers)
{
ChannelDispatcher cd = cdb as ChannelDispatcher;
cd.ErrorHandlers.Add(eh);
}
}
public void AddBindingParameters(ServiceDescription serviceDescription,
ServiceHostBase serviceHostBase,
Collection<ServiceEndpoint> endpoints,
BindingParameterCollection bindingParameters)
{
//Add binding parameters if you want, I am not
}
public void Validate(ServiceDescription serviceDescription,
ServiceHostBase serviceHostBase)
{
//Add custom fault validation here if you want
}
}
然后你需要将CustomErrorHandler添加为服务行为并添加行为
网络配置
<system.serviceModel>
<extensions>
<behaviorExtensions>
<add name="ErrorHandler"
type="ServiceNamespace.CustomErrorHandler, ServiceNamespace, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
</behaviorExtensions>
</extensions>
<behaviors>
<serviceBehaviors>
<behavior name="MyBehavior1">
<!--Put other behaviors for your service here then add the next line-->
<ErrorHandler />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
这样,您抛出的所有异常都将转换为错误以返回给客户端。
对于 SecurityTokenExceptions,您不希望立即将它们转换为错误异常。您实际上确实希望在自定义验证中将这些作为 SecurityTokenExceptions 抛出,以便服务/服务器识别安全授权失败,并自动返回错误,相当于“403:访问被拒绝”。我不是 100%,但我认为自定义身份验证和验证部分发生在自定义服务行为(如错误处理程序)加载之前。不幸的是,如果您需要对身份验证中的某些问题进行故障排除,则需要在服务上打开 WCF 跟踪,请参阅标题为“如何打开 WCF 跟踪”的文章。
如果您需要记录失败的身份验证尝试,您可能需要将其直接放入您的自定义验证器中。