Проверка подлинности NTLM не работает (400 и 500) - PullRequest
0 голосов
/ 26 ноября 2018

Привет, у меня есть простой клиент:

using System;
using System.ServiceModel;
using System.ServiceModel.Description;

namespace Ntlm
{
    public class Program
    {
        #region Methods

        private static void Main()
        {
            var t = new Program();
            Console.WriteLine("Starting....");
            t.Run();
        }

        private void Run()
        {
            // First procedure:
            // create a WSHttpBinding that uses Windows credentials and message security
            var myBinding = new WSHttpBinding
            {
                Security =
                {
                    Mode = SecurityMode.Message, Message = {ClientCredentialType = MessageCredentialType.Windows}
                }
            };

            // 2nd Procedure:
            // Use the binding in a service
            // Create the Type instances for later use and the URI for 
            // the base address.
            var contractType = typeof(ICalculator);
            var serviceType = typeof(Calculator);
            var baseAddress = new Uri("http://localhost:8036/SecuritySamples");

            // Create the ServiceHost and add an endpoint, then start
            // the service.
            var myServiceHost = new ServiceHost(serviceType, baseAddress);
            myServiceHost.AddServiceEndpoint(contractType, myBinding, "secureCalculator");

            //enable metadata
            var smb = new ServiceMetadataBehavior {HttpGetEnabled = true};
            myServiceHost.Description.Behaviors.Add(smb);

            myServiceHost.Open();
            Console.WriteLine("Listening");
            Console.WriteLine("Press Enter to close the service");
            Console.ReadLine();
            myServiceHost.Close();
        }

        #endregion
    }

    [ServiceContract]
    public interface ICalculator
    {
        #region Public Methods and Operators

        [OperationContract]
        double Add(double a, double b);

        #endregion
    }

    public class Calculator : ICalculator
    {
        #region Public Methods and Operators

        public double Add(double a, double b)
        {
            return a + b;
        }

        #endregion
    }
}

и в app.config нет ничего, кроме system.diagnostics

, сейчас я пытаюсь отправить

HttpWebRequest

, чтобы получить ответ от этой службы.Тестовый клиент Wcf может, конечно, сделать это при аутентификации с помощью этой службы при сканировании службы, а затем отправить запрос следующим образом:

<s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://www.w3.org/2003/05/soap-envelope">
  <s:Header>
    <a:Action s:mustUnderstand="1">http://tempuri.org/ICalculator/Add</a:Action>
    <a:MessageID>urn:uuid:dcac8c1e-b552-4011-8cf6-a0d3829aec71</a:MessageID>
    <a:ReplyTo>
      <a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
    </a:ReplyTo>
  </s:Header>
  <s:Body>
    <Add xmlns="http://tempuri.org/">
      <a>0</a>
      <b>0</b>
    </Add>
  </s:Body>
</s:Envelope>

СЕЙЧАС: в зависимости от того, что я отправляю, я получаю разные результаты сПроверка подлинности NTLM

CASE 1:

Я отправляю запрос

<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">
  <s:Body>
    <Add xmlns="http://tempuri.org/">
      <a>1</a>
      <b>1</b>
    </Add>
  </s:Body>
</s:Envelope>

с заголовками

Application-Type application / soap + xml; charset =utf-8; action = "http://tempuri.org/ICalculator/Add"

Я получаю 400 неверных запросов, и вот как я его отправляю:

    var req = WebRequest.CreateHttp(m.GetUri());
    req.Timeout = Timeout;
    req.AllowAutoRedirect = m.AutoRedirect;
    req.Method = "Post";
    req.AuthenticationLevel = AuthenticationLevel.MutualAuthRequested;
    req.Credentials = new CredentialCache {
            { Destination.Host, Destination.Port, "NTLM", new NetworkCredential(Config.Username, Config.Password, Config.AuthenticationDomain) },
    };
    req.Proxy.Credentials = request.Credentials;

    req.ContentType = "application/soap+xml;charset=utf-8;action=\"http://tempuri.org/ICalculator/Add\""

Случай 2: Я отправляю полезную нагрузку

<?xml version="1.0" encoding="utf-8"?><s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"><Header xmlns="http://www.w3.org/2003/05/soap-envelope"><Action xmlns="http://www.w3.org/2005/08/addressing">http://tempuri.org/ICalculator/Add</Action></Header>
  <s:Body>
    <Add xmlns="http://tempuri.org/">
      <a>1</a>
      <b>1</b>
    </Add>
  </s:Body>
</s:Envelope>

с теми же настройками, что и выше, и я получаю 500 Внутренняя ошибка сервера

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
  <s:Header>
    <a:Action s:mustUnderstand="1">http://www.w3.org/2005/08/addressing/soap/fault</a:Action>
  </s:Header>
  <s:Body>
    <s:Fault>
      <s:Code>
        <s:Value>s:Sender</s:Value>
        <s:Subcode>
          <s:Value xmlns:a="http://schemas.xmlsoap.org/ws/2005/02/sc">a:BadContextToken</s:Value>
        </s:Subcode>
      </s:Code>
      <s:Reason>
        <s:Text xml:lang="de-AT">The message could not be processed. This is most likely because the action 'http://tempuri.org/ICalculator/Add' is incorrect or because the message contains an invalid or expired security context token or because there is a mismatch between bindings. The security context token would be invalid if the service aborted the channel due to inactivity. To prevent the service from aborting idle sessions prematurely increase the Receive timeout on the service endpoint's binding.</s:Text>
      </s:Reason>
    </s:Fault>
  </s:Body>
</s:Envelope>

После анализа журналов WCF, fiddler и wireshark я вижу, что сообщение отправляется голым в моем случае,и проблема не приходит как-то, и нет 401 для моего кода. в чем проблема? У меня такая же проблема с Kerberos

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...