在CheckAccessCore

时间:2016-06-02 06:02:08

标签: c# wcf security wcf-security access-denied

我有一个配置了TransportWithMessageCredential安全性的WCF服务。 IAuthorizationPolicyServiceAuthenticationManagerServiceAuthorizationManager的所有三种实施都已到位且有效。

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() });

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

我在客户端尝试了各种try catch,甚至在操作中添加了FaultContract,但问题仍然存在。

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

enter image description here

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

更新

值得注意的是,我正在使用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);
        }
    }

但是这个事件调用客户端不会得到异常,并且调试事件中会出现相同的“未处理异常”。

我可以使调用客户端失败的唯一方法是在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); } }

.border

WCF追踪: enter image description here

2 个答案:

答案 0 :(得分:1)

你不应该期待一个FaultException,而是一个通信异常,在你的情况下是SecurityAccessDeniedException。我希望在这个阶段提出的所有例外都是沟通问题,因为关于沟通问题,安全问题是沟通问题的一部分。

答案 1 :(得分:0)

请尝试更改代码类型,如下所示:

<bindings>
    <wsHttpBinding>
        <binding name="NoSecurityBinding" >
            <security mode="None">
                <transport clientCredentialType="None"/>
                <message clientCredentialType="None"/>
            </security>
        </binding>
        <binding name="DefaultBinding" />
    </wsHttpBinding>
</bindings>