C# 具有Kerberos身份验证的WCF消息检查器错误

C# 具有Kerberos身份验证的WCF消息检查器错误,c#,wcf,C#,Wcf,我有一个WCF服务主机和预配置的消息检查器,用于根据XSD模式和总体消息大小验证消息。下面是它的实现 public class SimpleMessageInspector : IDispatchMessageInspector { private AsyncAPISender _messageSender = new AsyncAPISender(); private ILog logger = LogManager.GetLogger(typeof(SimpleMessage

我有一个WCF服务主机和预配置的消息检查器,用于根据XSD模式和总体消息大小验证消息。下面是它的实现

public class SimpleMessageInspector : IDispatchMessageInspector
{
    private AsyncAPISender _messageSender = new AsyncAPISender();
    private ILog logger = LogManager.GetLogger(typeof(SimpleMessageInspector));
    private readonly XmlSchemaSet _schemas;
    // Max packet syze 50 Mb by default
    private const int MaxPacketSizeByDefault = 52428800;

    //Other methods of IDispatchMessageInspector

    public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
    {
        logger.DebugFormat("Recieved SOAP message: {0}", request);

        var mb = request.CreateBufferedCopy(int.MaxValue);

        request = mb.CreateMessage();
        var copyForValidation = mb.CreateMessage();
        var copyForCheckSize = mb.CreateMessage();

        ValidateMessage(ref copyForValidation);

        CheckMessageSize(mb, ref copyForCheckSize);

        return null;
    }

    void ValidateMessage(ref System.ServiceModel.Channels.Message message)
    {
        XmlDocument bodyDoc = new XmlDocument();
        bodyDoc.Load(message.GetReaderAtBodyContents().ReadSubtree());
        XmlReaderSettings settings = new XmlReaderSettings();
        settings.Schemas.Add(_schemas);
        settings.ValidationType = ValidationType.Schema;
        XmlReader r = XmlReader.Create(new XmlNodeReader(bodyDoc), settings);

        try
        {
            while (r.Read()) { }
        }
        catch (Exception e)
        {
            throw new ArgumentException("Error on validation by xsd schema", e);
        }
    }

    private void CheckMessageSize(MessageBuffer buffer, ref Message message)
    {
        int maxPacketSize;
        var maxPacketSizeFromConfig = ConfigurationManager.AppSettings["MaxPacketSize"];
        if (!Int32.TryParse(maxPacketSizeFromConfig, out maxPacketSize))
        {
            maxPacketSize = MaxPacketSizeByDefault;
        }

        if (buffer.BufferSize > maxPacketSize)
        {
            var messageInfo = GetMessageInfoType(ref message);
            if (messageInfo != null)
                _messageSender.CreateResultTask(messageInfo, null, "Max message size exceeded", false);

            throw new Exception("Max message size exceeded");
        }
    }
}
当主机接收到消息“我有一个异常”此消息无法支持操作,因为它已被读取“当主机使用Kerberos绑定与basicHttp时,它只会提示一切正常。下面是导致错误的绑定配置

<binding name="customKerberosBinding">
  <security authenticationMode="Kerberos" allowInsecureTransport="true" enableUnsecuredResponse="false" requireDerivedKeys="false" protectTokens="false" requireSignatureConfirmation="false" messageSecurityVersion="WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10"></security>
  <textMessageEncoding messageVersion="Soap11"></textMessageEncoding>
            <httpTransport maxReceivedMessageSize="2000000000"></httpTransport>
</binding>


有什么解释为什么只在kerberos绑定和可能的解决方案上发生吗?

根据我使用
IDispatchMessageInspector
的经验,您只能读取一次消息。由于您阅读了它,并且它是通过引用传递的,我认为这就是为什么您会得到这个错误。在我的ValidateMessage方法中,在我进行验证之后,我创建了一个消息副本并返回它

object IDispatchMessageInspector.AfterReceiveRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel, System.ServiceModel.InstanceContext instanceContext)
{
    if (validateRequest)
    {
        if (!request.IsEmpty && !request.IsFault)
        {
            request = ValidateRequestMessageBody(request);
            channel.Close();
            channel.Dispose();
        }
    }
    return null;
}

private Message ValidateRequestMessageBody(System.ServiceModel.Channels.Message message)
{
    //do stuff
    var reader = XmlReader.Create(memStream, settings);                        
    var newMessage = Message.CreateMessage(reader, int.MaxValue, message.Version);
    newMessage.Headers.Clear();
    newMessage.Headers.CopyHeadersFrom(message.Headers);
    return newMessage;
}

根据我使用
IDispatchMessageInspector
的经验,您只能读取一次消息。由于您阅读了它,并且它是通过引用传递的,我认为这就是为什么您会得到这个错误。在我的ValidateMessage方法中,在我进行验证之后,我创建了一个消息副本并返回它

object IDispatchMessageInspector.AfterReceiveRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel, System.ServiceModel.InstanceContext instanceContext)
{
    if (validateRequest)
    {
        if (!request.IsEmpty && !request.IsFault)
        {
            request = ValidateRequestMessageBody(request);
            channel.Close();
            channel.Dispose();
        }
    }
    return null;
}

private Message ValidateRequestMessageBody(System.ServiceModel.Channels.Message message)
{
    //do stuff
    var reader = XmlReader.Create(memStream, settings);                        
    var newMessage = Message.CreateMessage(reader, int.MaxValue, message.Version);
    newMessage.Headers.Clear();
    newMessage.Headers.CopyHeadersFrom(message.Headers);
    return newMessage;
}