none
Couldnt get custom behavior extension listed in WCF-Custom Send adapter configuration wizard!!! RRS feed

  • Question

  • We have a requirement to pass WS-Security Usernametoken in plain text using SOAP 1.1 standard in order to invoke a web service hosted in PeopleSoft. Here is sample SOAP header that worked fine when I tested with SoapUI,

    <soapenv:Header xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
     <wsse:Security  xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
       <wsse:UsernameToken>
           <wsse:Username>#user#</wsse:Username>
            <wsse:Password>#pwd#</wsse:Password>
       </wsse:UsernameToken>
     </wsse:Security>
    </soapenv:Header>

    I could not find any available binding/behavior configurations with WCF-WsHTTP adapter to satisfy the requirement. So I thought of using WCF-Custom Send SolicitResponse type of adapter with a custom behavior extension to add the custom SOAP header described above. I've done the following steps as described in this blog .

    • Created classes implementing BehaviorExtensionElement,IEndPointBehavior and IClientMessageInspector
    • Deployed assembly into GAC
    • Added an entry for my behavior extension class under system.serviceModel\extensions\behaviorExtensions in machine.config(@ C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG)
    • Restarted Biztalk Server and reopened Admin Console

    This really seemed to be very simple and straight forward thing to do before I started doing. But for some reason, I could not see my behavior extension listed in the WCF-Custom adapter configuration. I may be missing some obvious stuff here!!! Any suggestions to resolve this issue would be highly appreciated.

    TIA,
    Rajesh


    Sr Consultant
    Thursday, May 28, 2009 2:25 PM

Answers

  • I could see my custom behavior extension after doing the following tasks (after looking at Denny's blog here ),

    1. space should be there between each component of type value in the machine.config entry as shown below

    Wrong : <add name="mySecurityBehavior" type="<namespace>.PSSecurityBehaviorExtension,ASSEMBLY(DLL)_NAME_HERE,Version=1.0.0.0, Culture=neutral,PublicKeyToken=PUBLIC_KEY_TOKEN_HERE" />

    Correct: <add name="mySecurityBehavior" type="<namespace>.PSSecurityBehaviorExtension, ASSEMBLY(DLL)_NAME_HERE, Version=1.0.0.0,  Culture=neutral, PublicKeyToken=PUBLIC_KEY_TOKEN_HERE" />

    2. Apply button has to be clicked after feeding values into General and Binding tabs in the WCF-Custom configuration wizard. Then only custom behavior extension elments are shown when we right click on Endpoint Behavior and choose Add Extension.(I am not sure, if this really is a constraint!!)

    Jeevitha and Abhinav, Thanks for your assistance.


    Sr Consultant
    Monday, June 15, 2009 7:55 PM

All replies

  • Have you overridden the BehaviorType property in your BehaviorExtensionElement class? Can you make sure that you are returning your endpoint behavior type as the BehaviorType?

    Thanks,
    Jeevitha

    Friday, May 29, 2009 12:45 PM

  • Jeevitha,

    Thanks for the reply. Yes, I have overridden the BehaviorType property  and returning endpoint behavior type as the BehaviorType. Please find below the partial code snippet for implementation of BehaviorExtensionElement,IEndPointBehavior and IClientMessageInspector.

    Do I need to declare custom Endpoint implementor class also in machine.config as I did with custom BehaviorExtension?

     

    public sealed class PSSecurityBehaviorExtension : BehaviorExtensionElement

    {

    [ConfigurationProperty("ServiceUsername", DefaultValue = "", IsRequired = true)]

     

    public string ServiceUsername

    {

     

    get

    {

     

    return (string)base["ServiceUsername"];

    }

     

    set

    {

     

    base["ServiceUsername"] = value;

    }

    }

    [

    ConfigurationProperty("ServicePassword", DefaultValue = "", IsRequired = true)]

     

    public string ServicePassword

    {

     

    get

    {

     

    return (string)base["ServicePassword"];

    }

     

    set

    {

     

    base["ServicePassword"] = value;

    }

    }

     

    protected override object CreateBehavior()

    {

     

    MyBehaviorConfiguration behaviorConfiguration = new MyBehaviorConfiguration(this.ServiceUsername, this.ServicePassword);

     

    return new PSSecurityEndpointBehavior(behaviorConfiguration);

    }

     

    public override Type BehaviorType

    {

     

    get

    {

     

    return typeof(PSSecurityEndpointBehavior);

    }

    }

     

     

    private ConfigurationPropertyCollection _prop = null;

     

    protected override ConfigurationPropertyCollection Properties

    {

     

    get {

     

    if (this._prop == null)

    {

     

    this._prop = new System.Configuration.ConfigurationPropertyCollection();

    }

     

    this._prop.Add(new System.Configuration.ConfigurationProperty("ServiceUsername", typeof(string), "", System.Configuration. ConfigurationPropertyOptions.IsRequired));

     

    this._prop.Add(new System.Configuration.ConfigurationProperty("ServicePassword", typeof(string), "", System. Configuration.ConfigurationPropertyOptions.IsRequired));

     

    return this._prop;

    }

    }

     

     

     

    }

     

    public class PSSecurityEndpointBehavior : IEndpointBehavior

    {

     

    public PSSecurityEndpointBehavior(MyBehaviorConfiguration behaviorConfiguration)

    {

     

    this.BehaviorConfiguration = behaviorConfiguration;

    }

     

    private MyBehaviorConfiguration behaviorConfig;

     

    public MyBehaviorConfiguration BehaviorConfiguration {

     

    get { return behaviorConfig;}

     

    set { behaviorConfig=value;}

    }

    public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters) { }

     

    public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)

    {

    clientRuntime.MessageInspectors.Add(

    new CustomHeadersMessageInspector(this.BehaviorConfiguration));

    }

     

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)

    { }

     

    public void Validate(ServiceEndpoint endpoint) { }

     

    }

    public

    class CustomHeadersMessageInspector : IClientMessageInspector

    {

     

    public CustomHeadersMessageInspector(MyBehaviorConfiguration behaviorConfiguration)

    {

     

    this.BehaviorConfiguration = behaviorConfiguration;

    }

     

    private MyBehaviorConfiguration behaviorConfig;

     

    public MyBehaviorConfiguration BehaviorConfiguration

    {

     

    get { return behaviorConfig; }

     

    set { behaviorConfig = value; }

    }

     

    public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState) { }

     

    public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, IClientChannel channel)

    {

    request.Headers.Add(BuildSecurityHeaders(

    this.BehaviorConfiguration.UserName,this.BehaviorConfiguration.Password));

     

    return null;

    }

     

     

    private MessageHeader BuildSecurityHeaders(string user, string pwd)

    {

     

    SecurityHeader msgHeader=new SecurityHeader();

    msgHeader.userToken =

    new UsernameToken();

    msgHeader.userToken.UserName = user;

    msgHeader.userToken.Password = pwd;

     

    return msgHeader;

    }

    }


    Sr Consultant
    Friday, May 29, 2009 1:47 PM
  • No, you don't have to register the endpointbehavior classes in machine.config. Adding the BehaviorExtension class should be fine.

    Can you make sure that you have specified the type and dll name without any mistakes?

    In your case it should look something like,
    <add name="mySecurityBehavior" type="<namespace>.PSSecurityBehaviorExtension , ASSEMBLY(DLL)_NAME_HERE, Version=1.0.0.0, Culture=neutral, PublicKeyToken=PUBLIC_KEY_TOKEN_HERE" />

    Thanks,
    Jeevitha

    Monday, June 1, 2009 6:35 AM
  • Yes. I did doublecheck the machine.config entry. I couldnt find any issue with that. Here is the entry that I have,

    <

    add name="mySecurityBehavior" type="PSSecurityBehaviorExtension.PSSecurityBehaviorExtension,PSSecurityBehaviorExtension, Version=1.0.0.0, Culture=neutral,PublicKeyToken=<key>" />


    Sr Consultant
    Monday, June 1, 2009 1:39 PM
  • Hi Rajesh,

    I have tried to create a similar extension element and it works fine. I followed the same steps that you have mentioned.

    Were you able to resolve this?
    Can you try to create some other endpointbehavior and see if it is a machine specific issue. This link(http://blogs.msdn.com/adapters/attachment/7146467.ashx) has an example behavior which you can give a try..

    Thanks,
    Jeevitha
    Friday, June 5, 2009 9:19 AM
  • Can you try restarting your BizTalk Services and close and then reopen the management console ?


    Abhinav
    Friday, June 5, 2009 11:49 AM
  • I could see my custom behavior extension after doing the following tasks (after looking at Denny's blog here ),

    1. space should be there between each component of type value in the machine.config entry as shown below

    Wrong : <add name="mySecurityBehavior" type="<namespace>.PSSecurityBehaviorExtension,ASSEMBLY(DLL)_NAME_HERE,Version=1.0.0.0, Culture=neutral,PublicKeyToken=PUBLIC_KEY_TOKEN_HERE" />

    Correct: <add name="mySecurityBehavior" type="<namespace>.PSSecurityBehaviorExtension, ASSEMBLY(DLL)_NAME_HERE, Version=1.0.0.0,  Culture=neutral, PublicKeyToken=PUBLIC_KEY_TOKEN_HERE" />

    2. Apply button has to be clicked after feeding values into General and Binding tabs in the WCF-Custom configuration wizard. Then only custom behavior extension elments are shown when we right click on Endpoint Behavior and choose Add Extension.(I am not sure, if this really is a constraint!!)

    Jeevitha and Abhinav, Thanks for your assistance.


    Sr Consultant
    Monday, June 15, 2009 7:55 PM