2
votes

In my application I am consuming a web service and i am using a custom class to create the usernametoken in the header of the soap request with username and password while I am calling the web service function.

Ref to the custom class I made for making header :- https://msdn.microsoft.com/en-us/library/ms730868(v=vs.110).aspx

But when i use the xmlns: wsse I am getting internal error and when I use xmlns:o for the <security> tag in the header I am getting null response.

The same application works fine if I add the username and password in config as

<headers>
    <wsse:Security mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
      <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
        <wsse:Username>username</wsse:Username>
        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">password</wsse:Password>
      </wsse:UsernameToken>
    </wsse:Security>
   </headers>

I want to change the username and password for differnet calls to the same webservice so i am using the custom class and generating header ,unfortunately it become the wcf auhtentication where the security tag look like this :-

      <o:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
        <o:Username></o:Username>
        <o:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText"></o:Password>
      </o:UsernameToken>

And this returns null for my function call. Any idea how I can make it work ? Any suggestion will be really appreciated.

Note: Its saying that Microsoft .net deprecated the use of wse and updated to wcf authentication. But it works for me with wsse and username and password in the config file ,but then I cannot change the username and password for different function calls in the webservice.

My code to initialise the webservice and call the method is as follows:-

  string endpointUri = @"https://my endpoint url";
                var endpoint = new System.ServiceModel.EndpointAddress(endpointUri);

                // Create binding using HTTPS
                var securityElement = System.ServiceModel.Channels.SecurityBindingElement.CreateUserNameOverTransportBindingElement();
                securityElement.IncludeTimestamp = true;
                securityElement.EnableUnsecuredResponse = true;
                securityElement.DefaultAlgorithmSuite = SecurityAlgorithmSuite.Basic256;
                securityElement.MessageSecurityVersion = MessageSecurityVersion.WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10;
                var encodingElement = new System.ServiceModel.Channels.TextMessageEncodingBindingElement(System.ServiceModel.Channels.MessageVersion.Soap11, System.Text.Encoding.UTF8);
                var transportElement = new System.ServiceModel.Channels.HttpsTransportBindingElement();
                transportElement.MaxReceivedMessageSize = 20000000;
                var binding = new System.ServiceModel.Channels.CustomBinding(securityElement, encodingElement, transportElement);
                QTWebSvcsClient client = new QTWebSvcsClient(binding, endpoint);

                //==========================================================================================================================

                client.ChannelFactory.Endpoint.Behaviors.Remove<ClientCredentials>();
                client.ChannelFactory.Endpoint.Behaviors.Add(new MyClientCredetnials());
                client.ClientCredentials.UserName.UserName = userName + "@" + comp;
                client.ClientCredentials.UserName.Password = password;

                getDriverDetailsRequest request = new getDriverDetailsRequest();
                request.driverId = "Driver1";

                getDriverDetailsResponse response = new getDriverDetailsResponse();
                response.getDriverDetailsReturn = client.getDriverDetails(request.driverId);

Which returns null to my code and I get exception for referencing the null object here

Console.WriteLine(response.getDriverDetailsReturn.driverName);
1
IT seems my web service's wsdl doesn't support the WCF application and created a ticket on the support team now they are making it work for WCF too. Earlier it only set for wsse security on it. Hopefully once they make the changeAntony

1 Answers

1
votes

I decided to not to follow the hard way instead i can just achieve my real requirement - Change the web security credentials dynamically through program.

I just used the config file codes auto created when you add a webservice reference to the C# application.

then in code I sued

BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.TransportWithMessageCredential);
                binding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName;
                CustomBinding customBinding = new CustomBinding(binding);
                SecurityBindingElement element = customBinding.Elements.Find<SecurityBindingElement>();
                element.IncludeTimestamp = false;
                EndpointAddress epadd = new EndpointAddress("https://mycompany.ca:113/tracsWebWS/services/TWebSvcs");
                TWebSvcsClient client = new TWebSvcsClient(customBinding, epadd);
                client.ClientCredentials.UserName.UserName = userName;
                client.ClientCredentials.UserName.Password = password;

then call the function through web service gave me the answer that I am looking for.

Thank you everyone who helped me with suggestions though.