Сертификат клиента WebRequest null на стороне WebAPI
У меня есть действие контроллера WebApi, которое я украсил своим атрибутом [x509Authorize]
. Я отлаживаю эту конечную точку локально - и в то же время запускаю консольное приложение, которое пытается вызвать эту конечную точку.
Клиентская сторона
Вот код клиента-немного упрощенный:
X509Certificate Cert = X509Certificate.CreateFromCertFile("C:\Temp\ht-android-client.pfx");
HttpWebRequest Request = (HttpWebRequest)WebRequest.Create("https://localhost:44300/api/mobile/predict");
Request.ClientCertificates.Add(Cert);
HttpWebResponse Response = (HttpWebResponse)Request.GetResponse();
....
Я утверждал, что Cert
является правильным сертификатом. Я установил .pfx
в моем CurrentUserPersonal
магазине и в LocalMachinePersonal
магазине-и модифицировал, чтобы взять сертификат из этого магазина, как было предложено здесь , но это, похоже, не имеет значения:
var store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly);
var Cert = store.Certificates.Find(X509FindType.FindBySubjectName, "Android", true)[0];
Серверная сторона
И я слушаю на конечной точке WebAPI, как со следующим кодом:
public class x509AuthorizeAttribute : AuthorizeAttribute
{
public override Task OnAuthorizationAsync(HttpActionContext actionContext, CancellationToken cancellationToken)
{
var cert = actionContext.Request.GetClientCertificate();
// value of 'cert' is null
Сначала я нажимаю точку останова в консольном приложении-смотрите, что выбран правильный сертификат. Затем я нажимаю точку останова на сервере и вижу, что значение .GetClientCertificate()
равно null
. Что я делаю не так? Остальные так Вопросы 1 и еще 2 мне это не помогло. дальнейший.
Дополнительная информация о сертификатах
Я создал самозаверяющий сертификат CA, который устанавливается в хранилище LocalMachineTrusted root CA
. Я создал сертификат клиента android и подписал его своим самозаверяющим сертификатом CA. Затем я преобразовал его в файл pkcs12
. Это сертификат, который использует клиент - который также установлен в моих личных хранилищах (как машина, так и currentUser ) и является действительным ( вы можете видеть, что цепочка возвращается к корневому сертификату CA ).
1 ответ:
Таким образом, проблема действительно заключается в том, что сервер должен иметь следующий набор в сети.config для того, чтобы заставить IIS начать согласование SSL cert:
<security> <access sslFlags="SslNegotiateCert" /> </security>
Если этого нет-сертификат будет проигнорирован и вы получите
null
по вызовуGetClientCertificate()
.Это означает, однако, что все клиенты для моего WebAPI теперь вынуждены предоставлять действительный сертификат - так что моя первоначальная идея иметь только один метод контроллера, требующий сертификата, не кажется возможный.
Тогда есть проблема установки этого конфигурационного параметра в web.config, из-за ограничений для облачных служб Azure. Однако - Этот ответ дает решение для этого.
EDIT
На боковой ноте это не поддерживается пока в ASP.NET vNext (v rc-01-final)