在CheckAccessCore之后,WCF访问被拒绝的异常永远不会返回到客户端

Moh*_*hin 8 c# security wcf access-denied wcf-security

我有一个配置了TransportWithMessageCredential安全性的WCF服务.所有三种实现的IAuthorizationPolicy,ServiceAuthenticationManagerServiceAuthorizationManager到位,有效.

serviceHost.Credentials.ServiceCertificate.SetCertificate("CN=localhost");
serviceHost.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = new CustomValidator();
serviceHost.Credentials.UserNameAuthentication.UserNamePasswordValidationMode = System.ServiceModel.Security.UserNamePasswordValidationMode.Custom;

serviceHost.Authorization.PrincipalPermissionMode = PrincipalPermissionMode.Custom;
serviceHost.Authorization.ServiceAuthorizationManager = new MyServiceAuthorizationManager();
serviceHost.Authentication.ServiceAuthenticationManager = new MyServiceAuthenticationManager();
serviceHost.Authorization.ExternalAuthorizationPolicies = 
    new System.Collections.ObjectModel.ReadOnlyCollection<System.IdentityModel.Policy.IAuthorizationPolicy>(
        new MyAuthorizationPolicy[] { new MyAuthorizationPolicy() });
Run Code Online (Sandbox Code Playgroud)

据我所知,在ServiceAuthorizationManager继承的类中,在CheckAccessCore方法中,return false语句表示拒绝访问.这一切都很好,直到我希望客户端知道他有一个访问被拒绝的异常,其中服务停止向客户端返回任何内容,似乎服务线程被绞死.

我尝试了各种各样try catch的客户端甚至添加了一个FaultContract操作,但问题抵制.

我只能看到诊断工具中的两个错误事件.

在此输入图像描述

我的实现中缺少什么来获取服务通知用户访问被拒绝错误?

更新

值得注意的是,我说我正在使用RoutingService,现在我猜真正的原因RoutingService是以某种方式吃异常,但我不知道究竟发生了什么.即使我介入了所有可能的方法,但我没有找到它.

更新2

IErrorHandler到位了:

   public class ServiceErrorHandler : IErrorHandler
    {
        public bool HandleError(Exception error)
        {
            //You can log th message if you want.            
            return true;
        }

        public void ProvideFault(Exception error, MessageVersion version, ref Message msg)
        {
            if (error is FaultException)
                return;

            FaultException faultException = new FaultException(error.Message);
            MessageFault messageFault = faultException.CreateMessageFault();
            msg = Message.CreateMessage(version, messageFault, faultException.Action);
        }
    }
Run Code Online (Sandbox Code Playgroud)

但是事件与调用客户端不会得到异常,并且调试事件中将出现相同的"未处理异常".

我可以通过调用客户端失败的唯一方法是在BeforeSendReply方法中抛出一个异常IDispatchMessageInspector,我认为这不是一种方法,因为我CommunicationException在客户端而不是FaultException:

  public void BeforeSendReply(ref Message reply, object correlationState)
    {                        
        if (reply != null && reply.IsFault)
        {
            var messageFault = MessageFault.CreateFault(reply, Int32.MaxValue);
            throw new FaultException("Access was denied", messageFault.Code);
        }
    }
Run Code Online (Sandbox Code Playgroud)

WCF追踪: 在此输入图像描述

LeB*_*ste 1

您不应该期望这里出现FaultException,而是通信异常,在您的情况下是SecurityAccessDeniedException。我希望现阶段提出的所有例外情况都是通信问题,因为它涉及通信问题,安全问题是其中的一部分。