ClientMessageInspector不通过配置触发,而是通过代码工作

时间:2018-10-22 21:39:17

标签: wcf

我试图在ClientMessageInspector的标头中注入安全性信息。我在配置中添加了必要的行为信息。但是,该请求不会像调用BeforeSendRequest一样通过客户端消息检查器。有趣的是,如果我将行为添加到代码中,它将起作用并触发BeforeSendRequest。有人可以通过配置告诉它为什么不通过客户端消息检查器BeforeSendRequest吗。

按以下方式工作:-

DealioLibClient dealioServiceProxy = new DealioLibClient();

dealioServiceProxy.Endpoint.EndpointBehaviors.Add(new AuthBehavior());

无法通过配置工作:-

<?xml version="1.0" encoding="utf-8" ?>
  <configuration>
    <system.serviceModel>

      <bindings>
        <basicHttpBinding>
          <binding name="SOAPEndPoint1" />
        </basicHttpBinding>
      </bindings>
      <client>
        <endpoint address="http://localhost:90/DealioCapLinkSvc/DealioCapLinkSvc.svc/soap"
          binding="basicHttpBinding" bindingConfiguration="SOAPEndPoint1"
          contract="DealioService.IDealioLib" name="SOAPEndPoint1" />
      </client>
<behaviors>
        <serviceBehaviors>
            <behavior>
                <serviceMetadata httpGetEnabled="True" httpsGetEnabled="True" />
                <serviceDebug includeExceptionDetailInFaults="False" />
            </behavior>
        </serviceBehaviors>
        <!-- Security Behavior -->
        <endpointBehaviors>
            <behavior name="authBehavior">
                <authBehavior />
            </behavior>
        </endpointBehaviors>
    </behaviors>
    <extensions>
        <behaviorExtensions>
            <add name="authBehavior" type="CanadaDealio.AuthBehavior, CanadaDealio , Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
        </behaviorExtensions>
    </extensions>
    </system.serviceModel>
</configuration>

下面是“身份验证行为和客户端消息”检查器:-

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel.Channels;
using System.ServiceModel.Configuration;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

namespace CanadaDealio
{
    public class AuthBehavior : BehaviorExtensionElement, IEndpointBehavior
    {
        public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
        {

        }

        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
            ClientMessageInspector inspector = new ClientMessageInspector();
            clientRuntime.MessageInspectors.Add(inspector);
        }

        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
        {

        }

        public void Validate(ServiceEndpoint endpoint)
        {

        }

        protected override object CreateBehavior()
        {
            return new AuthBehavior();
        }

        public override Type BehaviorType
        {
            get { return typeof(AuthBehavior); }
        }
    }
}

下面是客户端消息检查器:-

namespace CanadaDealio
{
    public class ClientMessageInspector : IClientMessageInspector
    {
        public void AfterReceiveReply(ref Message reply, object correlationState)
        {

        }

        public object BeforeSendRequest(ref Message request, System.ServiceModel.IClientChannel channel)
        {
            // I do my logic here

            return null;
        }
    }
}

验证标题:-

namespace CanadaDealio
{
    public class AuthHeader : MessageHeader
    {
        private const string HEADER_NAME = "AuthHeader";
        private const string NAME_SPACE = "http://jll.security.service";
        private readonly AuthToken _token;

        public AuthHeader(AuthToken token)
        {
            _token = token;
        }

        public override string Name
        {
            get { return HEADER_NAME; }
        }

        public override string Namespace
        {
            get { return NAME_SPACE; }
        }

        protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
        {
            /* NOTE: XML Serializer applies encoding, making the request not so readable. Keeping it her for future reference.
            XmlSerializer serializer = new XmlSerializer(typeof(AuthToken));
            StringWriter textWriter = new StringWriter();
            serializer.Serialize(textWriter, this._token);
            textWriter.Close();
            string text = textWriter.ToString();
             * */

            writer.WriteElementString("UserID", _token.UserID);
            writer.WriteElementString("Token", _token.Token);
        }
    }
}

以下是身份验证令牌:-

namespace CanadaDealio
{
    [DataContract]
    public class AuthToken
    {
        [DataMember]
        public string UserID { get; set; }

        [DataMember]
        public string Token { get; set; }
    }
}

1 个答案:

答案 0 :(得分:1)

我们需要将“端点行为”配置添加到客户端端点,以使“行为扩展”生效。

<endpoint address="http://localhost:1300/" binding="basicHttpBinding"
                bindingConfiguration="BasicHttpBinding_IService" contract="ServiceReference1.IService"
                name="BasicHttpBinding_IService" behaviorConfiguration="authBehavior" />