Безопасность WCF: какой путь для многих серверов и идентичности серверов не имеет значения? - PullRequest
0 голосов
/ 09 марта 2011

Итак, я провел некоторое исследование и обнаружил, что, действительно, WCF не позволяет нам отправлять имя пользователя / пароль в виде открытого текста. Основной аргумент заключается в том, что « небезопасно, поскольку позволяет хакеру перехватывать учетные данные ». Следовательно, требуется безопасный канал, и для этого серверу необходим сертификат X.509.

Хорошо, точка взята. Но вот проблема: указанный сертификат должен быть доверенным на клиенте. Но почему?
Доверенный сертификат обычно используется на серверах, открытых в Интернете, чтобы клиенты могли проверить подлинность сервера (т. Е. Убедиться, что они не подключаются к поддельному серверу). Но что, если идентификация сервера не важна в данном контексте?

Мой продукт состоит из двух приложений. Давайте назовем их клиент и сервер 1 .
Основной сценарий таков:

  1. Пользователь подключается к сети, в которой установлен один или несколько из этих серверов и открывает клиент приложение
  2. клиент использует обнаружение WCF для поиска любых серверов в сети
    (или, опционально, пользователь может указать адрес сервера вручную)
  3. Пользователь выбирает, к какому серверу он хочет подключиться, и затем вводит имя пользователя / пароль для этого сервера
  4. Соединение установлено, клиент делает некоторые звонки на сервер от имени пользователя

Можно видеть, как в этом сценарии пользователю не нужно проверять, что сервер не является поддельным. Даже если бы он захотел, нечего проверять против . В конце концов, единственное, что мы знаем о сервере, это то, что он поддерживает наш протокол, и этот факт не нуждается в проверке.

Другими словами, мне нужна конфиденциальность связи и аутентификация клиента , но не аутентификация сервера .

Было бы достаточно плохо попросить моих клиентов приобрести сертификат у доверенного органа для каждого сервера, но было бы еще хуже, если бы не было возможности объяснить, зачем им это нужно.

Учитывая все вышеперечисленные моменты, я вижу три возможности:

  1. Дизайнеры WCF просто не думали об этом сценарии. То есть WCF его не поддерживает.
    (по крайней мере изначально; да, я знаю о творении Ярона Наве ).

  2. Я упускаю некоторые детали, из которых следует, что сертификату все-таки нужно доверять.

  3. Существует способ (неизвестный мне) использовать сертификат только для шифрования, а не для аутентификации сервера, и, таким образом, избегать превращения его в доверенный.

Итак, вопрос:

Какой из этих трех вариантов имеет место? И если это третий, что это за путь? (Мои пальцы скрещены за номер 3: -)

.
,


1 Важно отметить, что термин " server " здесь не используется в смысле "Интернет". Таким образом, сервер - это не компьютер в сети, а программа , которая устанавливается на некотором компьютере, необязательно даже подключенном к Интернету. И многие из них будут установлены разными пользователями на своих сайтах, чаще всего без моего ведома.

Ответы [ 2 ]

1 голос
/ 07 апреля 2011

Чтобы избежать проверки сертификата, добавьте в элемент system.serviceModel/behaviors/endpointBehaviors/behavior/clientCredentials/serviceCertificate следующее:

<authentication certificateValidationMode="None" />
0 голосов
/ 09 марта 2011

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

С точки зрения конфигурации «сервера» вы просто убедитесь, что установлена ​​пара ключей, и используйте элемент конфигурации <serviceCertificate> для его использования:

<behavior name="MyServiceBehavior">
    <!-- ... -->
    <serviceCertificate findValue="AcmeCorpServer" storeLocation="LocalMachine" storeName="My" X509FindType="FindBySubjectName" />
    <!-- ... -->
</behavior>

А затем на клиентах вы просто убедитесь, что у вас установлен открытый ключ и настроили поведение конечной точки:

<behavior name="MyEndpointBehavior">
    <!-- ... -->
    <clientCredentials>
        <clientCertificate findValue="MyClient" storeLocation="CurrentUser" storeName="My" X509FindType="FindBySubjectName" />
        <serviceCertificate>
            <defaultCertificate findValue="AcmeCorpServer" storeLocation="CurrentUser" storeName="TrustedPeople" X509FindType="FindBySubjectName" />
        </serviceCertificate>
    </clientCredentials>
    <!-- ... -->
</behavior>

Это более грубый подход к безопасности, но, похоже, он будет соответствовать вашим конкретным потребностям. По сути, это все равно что сказать «разрешить моему клиенту общаться с любой службой, которая может когда-либо существовать, если мы можем подтвердить, что личность является нашей личностью».

Наконец, если вы не можете / не хотите делать это с конфигурацией по какой-то причине (то есть вы не можете / не хотите помещать вещи в хранилища сертификатов), есть способы сделать это также программно: загрузка сертификата X.509 вручную, а затем присвоение его поведению клиент / сервер во время выполнения.

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