2017-04-27 8 views
1

XSDスキーマとメッセージサイズ全体でメッセージを検証するために、WCFサービスホストと事前構成されたメッセージインスペクタが用意されています。ここにその実装があります。ホストは、KerberosがbasicHttpのすべてがOKであるとの結合を使用する場合Kerberos認証でのWCFメッセージインスペクタエラー

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

ホストが、私は例外「それが読み込まれているため、このメッセージは、操作をサポートすることはできません」を持っているメッセージをrecievesそれだけheppens。ここにエラーを引き起こすバインディング設定があります。

<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> 

ケルベロスの拘束と考えられる解決策についてのみ説明がありますか?

答えて

0

IDispatchMessageInspectorを使用して私の経験では、メッセージは1度しか読むことができません。あなたの読んでそれが参照によって渡されているので、私はあなたがこのエラーを取得している理由だと思う。検証を行った後の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; 
}