Search code examples
c#wcfmtom

which security modes are allowed for WCF MTOM basicHttpBinding


I have created new wcf service with MTOM message-encoding in basicHttpBinding. Now I have question with security part, which security modes will allowed for WCF service -MTOM - basicHttpBinding

<basicHttpBinding>
    <binding name="DefaultBinding_Mtom" messageEncoding="Mtom" transferMode="Streamed" maxReceivedMessageSize="700000">
     <readerQuotas maxArrayLength="2147483647" maxBytesPerRead="2147483647" />
     <security mode="None">
       <transport clientCredentialType="None" proxyCredentialType="None" realm="" />
       <message clientCredentialType="UserName" algorithmSuite="Default" />
     </security>          
   </binding>
</basicHttpBinding>

In above code <security mode="None">, with this my service is working as expected in client. But when I have modified security mode NTLM <security mode="TransportCredentialOnly"> then i am facing issues while invoking service.

<security mode="TransportCredentialOnly">
  <transport clientCredentialType="Ntlm" proxyCredentialType="Windows" realm=""/>
  <message clientCredentialType="UserName" algorithmSuite="Default"/>
</security>

if my service is messageEncoding="Text" then working fine, even security mode is NTLM. So, which security mode are allowed for Mtom service and could you please guide me how to set security modes.

Thanks & Regards,


Solution

  • Neither the Text encoding nor the MTOM encoding will affect the invocation of the remote service. The following two security modes can use Windows Authentication. On my side, it works fine. Please tell me the details of the error.

    Uri uri = new Uri("http://localhost:21011");
                BasicHttpBinding binding = new BasicHttpBinding();
                binding.MessageEncoding = WSMessageEncoding.Mtom;
                binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
                binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
    

    Or,

    Uri uri = new Uri("https://localhost:21011");
                BasicHttpBinding binding = new BasicHttpBinding();
                binding.MessageEncoding = WSMessageEncoding.Mtom;
                binding.Security.Mode = BasicHttpSecurityMode.Transport;
                binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
    

    Here is my example.
    Server-side.

    class Program
    {
        static void Main(string[] args)
        {
            Uri uri = new Uri("http://localhost:21011");
            BasicHttpBinding binding = new BasicHttpBinding();
            binding.MessageEncoding = WSMessageEncoding.Mtom;
            binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
            binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
            using (ServiceHost sh = new ServiceHost(typeof(MyService), uri))
            {
                sh.AddServiceEndpoint(typeof(IService), binding,"");
                ServiceMetadataBehavior smb;
                smb = sh.Description.Behaviors.Find<ServiceMetadataBehavior>();
                if (smb == null)
                {
                    smb = new ServiceMetadataBehavior()
                    {
                        HttpGetEnabled = true
                    };
                    sh.Description.Behaviors.Add(smb);
                }
                Binding mexbinding = MetadataExchangeBindings.CreateMexHttpBinding();
                sh.AddServiceEndpoint(typeof(IMetadataExchange), mexbinding, "mex");
    
    
                sh.Opened += delegate
                {
                    Console.WriteLine("Service is ready");
                };
                sh.Closed += delegate
                {
                    Console.WriteLine("Service is clsoed");
                };
                sh.Open();
                Console.ReadLine();
                //pause
                sh.Close();
                Console.ReadLine();
            }
        }
    }
    [ServiceContract]
    public interface IService
    {
        [OperationContract]
        string Test();
    
    }
    public class MyService : IService
    {
        public string Test()
        {
            return DateTime.Now.ToLongTimeString();
        }
    }
    

    Client-side.(calling the remote service by using a client proxy)

    static void Main(string[] args)
            {
                ServiceReference1.ServiceClient client = new ServiceClient();
                client.ClientCredentials.Windows.ClientCredential.UserName = "administrator";
                client.ClientCredentials.Windows.ClientCredential.Password = "abcd1234!";
                var result = client.Test();
                Console.WriteLine(result);
    
            }
    

    Appconfig configuration on the client-side.

    <system.serviceModel>
        <bindings>
          <basicHttpBinding>
            <binding name="BasicHttpBinding_IService" messageEncoding="Mtom">
              <security mode="TransportCredentialOnly">
                <transport clientCredentialType="Windows" />
              </security>
            </binding>
          </basicHttpBinding>
        </bindings>
        <client>
          <endpoint address="http://10.157.13.69:21011/" binding="basicHttpBinding"
            bindingConfiguration="BasicHttpBinding_IService" contract="ServiceReference1.IService"
            name="BasicHttpBinding_IService" />
        </client>
      </system.serviceModel>
    

    Feel free to let me konow if there is anything I can help with.