Проверка подлинности NTLM не работает (400 и 500)
Привет, у меня есть простой клиент:
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
СЛУЧАЙ 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>
с заголовками
Приложение Content-Type /soap+xml;charset=utf-8;action="http://tempuri.org/ICalculator/Add"
Я получаю 400 Bad Request, и вот как я его отправляю:
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 Internal Server Error
<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