Я изучаю использование ServiceStack в качестве альтернативы WCF. Одно из моих требований заключается в том, что сервер и клиент должны взаимно аутентифицироваться с использованием сертификатов. Клиент — это служба, поэтому я не могу использовать какой-либо тип аутентификации, связанный с пользовательским вводом. Также клиент должен иметь возможность работать в Linux с использованием моно, чтобы аутентификация Windows не работала.
Я привязал свой сертификат сервера к порту моего сервера с помощью netsh.exe, подтвердил, что клиент получает сертификат сервера, а данные шифруются с помощью wireshark. Однако я не могу понять, как настроить сервер для запроса сертификата клиента.
Некоторые люди предлагали использовать фильтры запросов для проверки сертификата клиента, но это кажется очень неэффективным, поскольку каждый запрос будет проверять сертификат клиента. Производительность является очень высоким приоритетом. Создание пользовательского IAuthProvider кажется многообещающим, но вся документация и примеры ориентированы на типы аутентификации, которые в какой-то момент предполагают взаимодействие с пользователем, а не сертификаты.
https://github.com/ServiceStack/ServiceStack/wiki/Authentication-and-authorization
Можно ли использовать сертификаты для взаимной аутентификации клиента и сервера в собственной службе ServiceStack?
Вот мой тестовый сервис для справки.
public class Host : AppHostHttpListenerBase
{
public Host()
: base("Self-hosted thing", typeof(PutValueService).Assembly)
{
//TODO - add custom IAuthProvider to validate the client certificate?
this.RequestFilters.Add(ValidateRequest);
//add protobuf plugin
//https://github.com/ServiceStack/ServiceStack/wiki/Protobuf-format
Plugins.Add(new ProtoBufFormat());
//register protobuf
base.ContentTypeFilters.Register(ContentType.ProtoBuf,
(reqCtx, res, stream) => ProtoBuf.Serializer.NonGeneric.Serialize(stream, res),
ProtoBuf.Serializer.NonGeneric.Deserialize);
}
public override void Configure(Funq.Container container)
{}
void ValidateRequest(IHttpRequest request, IHttpResponse response, object dto)
{
//TODO - get client certificate?
}
}
[DataContract]
[Route("/putvalue", "POST")]
//dto
public class PutValueMessage : IReturnVoid
{
[DataMember(Order=1)]
public string StreamID { get; set; }
[DataMember(Order=2)]
public byte[] Data { get; set; }
}
//service
public class PutValueService : Service
{
public void Any(PutValueMessage request)
{
//Comment out for performance testing
Console.WriteLine(DateTime.Now);
Console.WriteLine(request.StreamID);
Console.WriteLine(Encoding.UTF8.GetString(request.Data));
}
}