Вызов службы WCF с базовой аутентификацией и сертификатом клиента - PullRequest
0 голосов
/ 05 июля 2019

Мы записываем клиента в службу WCF, которая использует как сертификат CSR, так и базовую аутентификацию.

Наш клиент C # генерируется с помощью Visual Studio, и мы можем программно установить сертификат и имя пользователя / пароль. Однако мы должны вручную отправить заголовок Basic Auth, в противном случае мы получим ошибку:

'The HTTP request is unauthorized with client authentication scheme 'Anonymous'. The authentication header received from the server was 'Basic realm="HttpBasicAuthentication"'.'

Наш код:

var myBinding = new WSHttpBinding();
myBinding.Security.Mode = SecurityMode.Transport;
myBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
myBinding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;

var ea = new EndpointAddress("https://example.org/myservice");
var client = new MandateWebServiceClient(myBinding, ea);
client.ClientCredentials.UserName.UserName = "wally";
client.ClientCredentials.UserName.Password = "walliesWorld";
client.ClientCredentials.ClientCertificate.Certificate = new X509Certificate2("C:\\some\\path\\to\\csr.pfx", "password");

using (var scope = new OperationContextScope(client.InnerChannel))
{
    var httpRequestProperty = new HttpRequestMessageProperty();
    httpRequestProperty.Headers[HttpRequestHeader.Authorization] =
        "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes(client.ClientCredentials.UserName.UserName + ":" + client.ClientCredentials.UserName.Password));
    OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;

    client.create();
}

С помощью приведенного выше кода мы можем успешно поговорить с сервисом. Если мы удалим строки в блоке using, схема аутентификации изменится на Anonymous, и мы получим ошибку выше.

Вышеуказанная договоренность кажется немного хаккейской. Мы перепробовали все возможные настройки SecurityMode, и SecurityMode.Transport с HttpClientCredentialType.Certificate - единственная комбинация, позволяющая принять сертификат. Настройка или не настройка MessageCredentialType.UserName, по-видимому, не влияет на систему.

Существует ли какой-либо .Net Framework способ предоставления как сертификата, так и основного заголовка аутентификации, вместо добавления заголовка вручную?

1 Ответ

0 голосов
/ 08 июля 2019

Как сервер использует как аутентификацию сертификата, так и обычную аутентификацию? Это кажется излишним. Поскольку проверка подлинности клиента с помощью сертификата безопасна (выдайте сертификат и установите отношения между сервером и клиентом), зачем нам нужно проверять подлинность клиента с помощью базовой проверки подлинности? Таким образом, вы уверены, что клиент должен предоставить сертификат? По моему мнению, сервер мог использовать режим безопасности транспорта и настроить обычную аутентификацию, поэтому клиенту может не потребоваться предоставлять сертификат.
Вот конфигурация на стороне сервера, о которой я думал.
Сервер.

Uri uri = new Uri("https://localhost:9900");
        WSHttpBinding binding = new WSHttpBinding();
        binding.Security.Mode = SecurityMode.Transport;
        binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;

Клиент (вызов путем добавления ссылки на службу, класс прокси-клиента / тип привязки генерируется автоматически через конечную точку MEX службы, https://localhost:9900/mex)

ServiceReference1.ServiceClient client = new ServiceReference1.ServiceClient();
            client.ClientCredentials.UserName.UserName = "administrator";
            client.ClientCredentials.UserName.Password = "abcd1234!";

Исходя из этого, у меня возникает вопрос, что представляет собой автоматически сгенерированный тип привязки на стороне клиента при вызове службы путем добавления ссылки на службу?
С нетерпением ждем вашего ответа.

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