我为WCF服务实现了自定义IAuthorizationPolicy
。它工作正常,除非授权失败,客户端收到无意义的错误。
如果我只是return false
方法中的Evaluate
,客户端就会收到此信息:
System.ServiceModel.FaultException :'由于内部错误,服务器无法处理请求。有关错误的更多信息,请在服务器上启用IncludeExceptionDetailInFaults(来自ServiceBehaviorAttribute或配置行为),以便将异常信息发送回客户端,或者根据Microsoft .NET Framework SDK文档打开跟踪,检查服务器跟踪日志。'
如果我抛出FaultException<MyCustomErrorDetails>
,客户端会收到:
System.ServiceModel.CommunicationException:&#39;接收到http://localhost:9034/Service1.svc的HTTP响应时发生错误。这可能是由于服务端点绑定不使用HTTP协议。这也可能是由于服务器中止HTTP请求上下文(可能是由于服务关闭)。有关详细信息,请参阅服务器日志。&#39;
哪个更没用。
如何向客户返回有意义的错误,例如&#34;授权失败&#34;?
答案 0 :(得分:1)
在WCF服务中启用详细的错误消息可以通过行为配置来完成:
<serviceBehaviors>
<behavior>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
通常,您将创建一个包含故障信息的类型,例如:
[DataContract]
public class SecurityFault
{
private string operation;
private string problemType;
[DataMember]
public string Operation
{
get { return operation; }
set { operation = value; }
}
[DataMember]
public string ProblemType
{
get { return problemType; }
set { problemType = value; }
}
}
在服务合同中,您需要使用故障合同来装饰操作,如下所示:
[ServiceContract]
public interface IService
{
[OperationContract]
[FaultContract(typeof(SecurityFault))]
int Divide(int number1, int number2);
}
在这种情况下,您将在授权策略中抛出异常,例如:
public class AuthorizationAlwaysFails : IAuthorizationPolicy
{
public ClaimSet Issuer => throw new NotImplementedException();
public string Id => Guid.NewGuid().ToString();
public bool Evaluate(EvaluationContext evaluationContext, ref object state)
{
var sf = new SecurityFault();
sf.Operation = "Authorization";
sf.ProblemType = "Authorization failed";
throw new FaultException<SecurityFault>(sf);
}
}
然后,客户端应用程序可以按如下方式捕获异常:
public class Program
{
static void Main(string[] args)
{
var wcfClient = new MyService.ServiceClient();
try
{
var result = wcfClient.Divide(10, 5);
Console.WriteLine(result);
}
catch (FaultException<SecurityFault> securityFault)
{
Console.WriteLine(securityFault.Detail.Operation);
Console.WriteLine(securityFault.Detail.ProblemType);
}
Console.ReadLine();
}
}