.NET Framework Developer Center > .NET Development Forums > Windows Communication Foundation > how do i make wcf client that'll talk to this wse service (with included policy)
Ask a questionAsk a question
 

Questionhow do i make wcf client that'll talk to this wse service (with included policy)

  • Friday, July 27, 2007 8:10 PMJames Peckham Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

     

    I’m using a service that is using username token authentication and it’s built in wse 3.0.

    http://msdn2.microsoft.com/en-US/library/aa480575.aspx

     

    I am trying to interop with it via wcf like so:

    http://msdn2.microsoft.com/en-us/library/ms730299.aspx

     

    Code Snippet

    the vendor who makes the service has given me the following policy file

    <policies xmlns="http://schemas.microsoft.com/wse/2005/06/policy">

      <extensions>

        <extension name="usernameOverTransportSecurity" type="Microsoft.Web.Services3.Design.UsernameOverTransportAssertion, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />

        <extension name="requireActionHeader" type="Microsoft.Web.Services3.Design.RequireActionHeaderAssertion, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />

      </< SPAN>extensions>

      <policy name="InsertNameHere">

        <usernameOverTransportSecurity />

        <requireActionHeader />

      </< SPAN>policy>

    </< SPAN>policies>

     

     

     

    However, the services are NOT on SSL they’re hosted on basic HTTP.

     

    I wrote the following client to try to talk to the service

     

    Code Snippet

               Console.Write("Logging in...");

     

                //Configure an anon binding so we can log in

                WseHttpBinding binding = new WseHttpBinding();

                binding.LoadPolicy("wse3policyCache.config", "InsertNameHere");

     

                LoginServiceSoapClient loginClient =

             new LoginServiceSoapClient(binding,

             new EndpointAddress("HTTP://myserver/myLoginService.asmx") );

                Guid guid = loginClient.LogIn("username", "myP4ssw0rd",true);

     

     

     

                Console.WriteLine("Logged in!");

                Console.WriteLine(" (press any key to exit) ");

                Console.ReadKey();

     

     

               

     

    Now I’m stuck because it says that http isn’t valid, but if I use https it can’t find the certificate, because there isn’t one.

     

    Thanks,

     

     

    the vendor has a wse client that talks to this service just fine but they don't know  anything about wcf yet, but we only use wcf and arent familiar with wse.

All Replies

  • Saturday, July 28, 2007 10:39 PMShiung Yong - MSFT Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    If I understand this scenario correctly, you are trying to write a WCF client which talks to a WSE service which exposes "usernameOverTransport" in its policy, but its not using transport security.

     

    Have you tried converting the generated Wse binding on the WCF client side, converting it to a custom binding, and replacing the transport security layer with a nonsecure HttpTransportBindingElement?

  • Monday, August 27, 2007 4:34 PMJames Peckham Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    YES! that is correct, this service utilizes usernameOverTransport but has no transport security (if that's bad i'd like to know why so i can tell the vendor to fix it). However, i do not know how to do what you're suggesting to try. I think we already have a 'custom binding' created from the example in wse samples at http://msdn2.microsoft.com/en-us/library/ms752257.aspx .

     

    looks like this:

    Code Snippet

    namespace Srg.Wse.Interop

    {

    public enum WseSecurityAssertion

    {

    UsernameOverTransport = 0,

    MutualCertificate10 = 1,

    UsernameForCertificate = 2,

    AnonymousForCertificate = 3,

    MutualCertificate11 = 4,

    Kerberos = 5

    }

    public class WseHttpBinding :Binding

    {

    public WseHttpBinding() { }

    public override BindingElementCollection CreateBindingElements()

    {

    //SecurityBindingElement sbe = bec.Find<SecurityBindingElement>();

    BindingElementCollection bec = new BindingElementCollection();

    // By default http transport is used

    SecurityBindingElement securityBinding;

    BindingElement transport;

    switch (assertion)

    {

    case WseSecurityAssertion.UsernameOverTransport:

    transport = new HttpsTransportBindingElement();

    securityBinding = (TransportSecurityBindingElement)SecurityBindingElement.CreateUserNameOverTransportBindingElement();

    if (establishSecurityContext == true)

    throw new InvalidOperationException("Secure Conversation is not supported for this Security Assertion Type");

    if (requireSignatureConfirmation == true)

    throw new InvalidOperationException("Signature Confirmation is not supported for this Security Assertion Type");

    break;

    case WseSecurityAssertion.MutualCertificate10:

    transport = new HttpTransportBindingElement();

    securityBinding = SecurityBindingElement.CreateMutualCertificateBindingElement(MessageSecurityVersion.WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10);

    if (requireSignatureConfirmation == true)

    throw new InvalidOperationException("Signature Confirmation is not supported for this Security Assertion Type");

    ((AsymmetricSecurityBindingElement)securityBinding).MessageProtectionOrder = messageProtectionOrder;

    break;

    case WseSecurityAssertion.UsernameForCertificate:

    transport = new HttpTransportBindingElement();

    securityBinding = (SymmetricSecurityBindingElement)SecurityBindingElement.CreateUserNameForCertificateBindingElement();

    // We want signatureconfirmation on the bootstrap process

    // either for the application messages or for the RST/RSTR

    ((SymmetricSecurityBindingElement)securityBinding).RequireSignatureConfirmation = requireSignatureConfirmation;

    ((SymmetricSecurityBindingElement)securityBinding).MessageProtectionOrder = messageProtectionOrder;

    break;

    case WseSecurityAssertion.AnonymousForCertificate:

    transport = new HttpTransportBindingElement();

    securityBinding = (SymmetricSecurityBindingElement)SecurityBindingElement.CreateAnonymousForCertificateBindingElement();

    ((SymmetricSecurityBindingElement)securityBinding).RequireSignatureConfirmation = requireSignatureConfirmation;

    ((SymmetricSecurityBindingElement)securityBinding).MessageProtectionOrder = messageProtectionOrder;

    break;

    case WseSecurityAssertion.MutualCertificate11:

    transport = new HttpTransportBindingElement();

    securityBinding = SecurityBindingElement.CreateMutualCertificateBindingElement(MessageSecurityVersion.WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11);

    ((SymmetricSecurityBindingElement)securityBinding).RequireSignatureConfirmation = requireSignatureConfirmation;

    ((SymmetricSecurityBindingElement)securityBinding).MessageProtectionOrder = messageProtectionOrder;

    break;

    case WseSecurityAssertion.Kerberos:

    transport = new HttpTransportBindingElement();

    securityBinding = (SymmetricSecurityBindingElement)SecurityBindingElement.CreateKerberosBindingElement();

    ((SymmetricSecurityBindingElement)securityBinding).RequireSignatureConfirmation = requireSignatureConfirmation;

    ((SymmetricSecurityBindingElement)securityBinding).MessageProtectionOrder = messageProtectionOrder;

    break;

    default:

    throw new NotSupportedException("This supplied Wse security assertion is not supported");

    }

    //Set defaults for the security binding

    securityBinding.IncludeTimestamp = true;

    // Derived Keys

    // set the preference for derived keys before creating SecureConversationBindingElement

    securityBinding.SetKeyDerivation(requireDerivedKeys);

    //Secure Conversation

    if (establishSecurityContext == true)

    {

    SymmetricSecurityBindingElement secureconversation =

    (SymmetricSecurityBindingElement)SymmetricSecurityBindingElement.CreateSecureConversationBindingElement(

    securityBinding, false);

    // This is the default

    //secureconversation.DefaultProtectionLevel = ProtectionLevel.EncryptAndSign;

    //Set defaults for the secure conversation binding

    secureconversation.DefaultAlgorithmSuite = SecurityAlgorithmSuite.Basic256;

    // We do not want signature confirmation on the application level messages

    // when secure conversation is enabled.

    secureconversation.RequireSignatureConfirmation = false;

    secureconversation.MessageProtectionOrder = messageProtectionOrder;

    secureconversation.SetKeyDerivation(requireDerivedKeys);

    securityBinding = secureconversation;

    }

    // Add the security binding to the binding collection

    bec.Add(securityBinding);

    // Add the message encoder.

    TextMessageEncodingBindingElement textelement = new TextMessageEncodingBindingElement();

    textelement.MessageVersion = MessageVersion.Soap11WSAddressingAugust2004;

    //These are the defaults required for WSE

    //textelement.MessageVersion = MessageVersion.Soap11Addressing1;

    //textelement.WriteEncoding = System.Text.Encoding.UTF8;

    bec.Add(textelement);

    // Add the transport

    bec.Add(transport);

     

    // return the binding elements

    return bec;

    }

    // Finds the named WSE 3.0 Policy and initialize the WseHttpBinding;

    public void LoadPolicy(String filename, String policyName)

    {

    bool readPolicy = false;

    XmlReader reader = XmlReader.Create(filename);

    reader.MoveToContent();

    if (!reader.ReadToDescendant("policy", "http://schemas.microsoft.com/wse/2005/06/policy"))

    throw new InvalidOperationException("The reader does not contain any Policy element. Check the policy file if it contains any policy.");

    do

    {

    if (reader["name"] == policyName)

    {

    reader.Read();

    reader.MoveToContent();

    switch (reader.Name)

    {

    case "usernameForCertificateSecurity":

    SecurityAssertion = WseSecurityAssertion.UsernameForCertificate;

    PolicyProperties(reader.ReadSubtree());

    break;

    case "usernameOverTransportSecurity":

    SecurityAssertion = WseSecurityAssertion.UsernameOverTransport;

    PolicyProperties(reader.ReadSubtree());

    break;

    case "mutualCertificate10Security":

    SecurityAssertion = WseSecurityAssertion.MutualCertificate10;

    PolicyProperties(reader.ReadSubtree());

    break;

    case "mutualCertificate11Security":

    SecurityAssertion = WseSecurityAssertion.MutualCertificate11;

    PolicyProperties(reader.ReadSubtree());

    break;

    case "anonymousForCertificateSecurity":

    SecurityAssertion = WseSecurityAssertion.AnonymousForCertificate;

    PolicyProperties(reader.ReadSubtree());

    break;

    case "kerberosSecurity":

    SecurityAssertion = WseSecurityAssertion.Kerberos;

    PolicyProperties(reader.ReadSubtree());

    break;

    // not used.

    case "authorization":

    case "requireSoapHeader":

    case "requireActionHeader":

    default:

    throw new NotSupportedException("The given policy contains unrecognized or unsupported security element.");

    }

    readPolicy = true;

    break;

    }

    } while (reader.ReadToNextSibling("policy", "http://schemas.microsoft.com/wse/2005/06/policy"));

    if (!readPolicy)

    throw new InvalidOperationException("The given policy name is not present in the given reader.");

    }

    void PolicyProperties(XmlReader reader)

    {

    reader.Read();

    //Set the Security Assertion XML attributes onto the binding properties

    while (reader.MoveToNextAttribute())

    {

    if (reader.Name == "establishSecurityContext")

    EstablishSecurityContext = reader.ReadContentAsBoolean();

    if (reader.Name == "requireSignatureConfirmation")

    RequireSignatureConfirmation = reader.ReadContentAsBoolean();

    if (reader.Name == "requireDerivedKeys")

    RequireDerivedKeys = reader.ReadContentAsBoolean();

    if (reader.Name == "messageProtectionOrder")

    {

    String protectionOrder = reader.Value;

    switch (protectionOrder)

    {

    case "SignBeforeEncrypt":

    MessageProtectionOrder = MessageProtectionOrder.SignBeforeEncrypt;

    break;

    case "EncryptBeforeSign":

    MessageProtectionOrder = MessageProtectionOrder.EncryptBeforeSign;

    break;

    case "SignBeforeEncryptAndEncryptSignature":

    MessageProtectionOrder = MessageProtectionOrder.SignBeforeEncryptAndEncryptSignature;

    break;

    }

    }

    }

    }

    public override string Scheme

    {

    get { return "http"; }

    }

    private WseSecurityAssertion assertion;

    public WseSecurityAssertion SecurityAssertion

    {

    get { return assertion; }

    set { assertion = value; }

    }

    private bool requireDerivedKeys;

    public bool RequireDerivedKeys

    {

    get { return requireDerivedKeys; }

    set { requireDerivedKeys = value; }

    }

    private bool establishSecurityContext;

    public bool EstablishSecurityContext

    {

    get { return establishSecurityContext; }

    set { establishSecurityContext = value; }

    }

    private bool requireSignatureConfirmation;

    public bool RequireSignatureConfirmation

    {

    get { return requireSignatureConfirmation; }

    set { requireSignatureConfirmation = value; }

    }

    private MessageProtectionOrder messageProtectionOrder;

    public MessageProtectionOrder MessageProtectionOrder

    {

    get { return messageProtectionOrder; }

    set { messageProtectionOrder = value; }

    }

     

    }

    }

     

     

     

    How would i go about replacing the  transport security layer?

     

     

     

     

     

     

  • Monday, August 27, 2007 4:38 PMJames Peckham Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

     

    hah ok, after actually reading the code i pasted, i see transport = httpsBindingElement()... i just need to change that to httpBinding element, right?

     

    i did this:

    Code Snippet

    case WseSecurityAssertion.UsernameOverTransport:

    transport = new HttpTransportBindingElement();

    securityBinding = (TransportSecurityBindingElement)SecurityBindingElement.CreateUserNameOverTransportBindingElement();

    if (establishSecurityContext == true)

    throw new InvalidOperationException("Secure Conversation is not supported for this Security Assertion Type");

    if (requireSignatureConfirmation == true)

    throw new InvalidOperationException("Signature Confirmation is not supported for this Security Assertion Type");

    break;

     

     

    but now i get:

     

    Code Snippet

    The 'WseHttpBinding'.'http://tempuri.org/' binding for the '******SERVICE NAME***'.'*****URI**************' contract is configured with an authentication mode that requires transport level integrity and confidentiality. However the transport cannot provide integrity and confidentiality.

     

     

    we aren't using ssl and the vendor's client works with their services fine... if you know what i'm missing please let me know. Thanks

     

  • Tuesday, August 28, 2007 7:43 PMAllan-Nielsen Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    Hi,

     

     Shiung Yong - MSFT wrote:

    If I understand this scenario correctly, you are trying to write a WCF client which talks to a WSE service which exposes "usernameOverTransport" in its policy, but its not using transport security.

     

    Have you tried converting the generated Wse binding on the WCF client side, converting it to a custom binding, and replacing the transport security layer with a nonsecure HttpTransportBindingElement?

     

    interesting, I might be overlooking the simple solution here, but the only way I can imagine this is if you implemented ISecurityCapabilites and then return false on all the Supportxxxx methods ?, return that interface in the GetProperty<T> in his own derived  HttpsTransportBindingElement class! (looking at JDPechams code there).

     

    is that what you saying here Yong ?

     

    Allan

     

     

     

  • Sunday, November 08, 2009 7:14 AMViVyVyVyVy Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    There is a work around for this.

    Use ClearUserPassBinding (search on google.)

    Its a custom binding code available on internet.

    Dont forget to set the Proper MessageVersion and includeTimestamp= false

    u also need to pass the credentials as well

    serviceCilentPortType.ClientCredentials.UserName.UserName =

    "username";

    serviceClientPortType.ClientCredentials.UserName.Password =

    "password";