Аутентификация клиента через сертификаты X509 в asp.net

У меня есть приложение asp.net, и мне нужно аутентифицировать пользователей с помощью сертификатов X509. То есть пользователь должен установить сертификат, выданный мной, чтобы он мог просматривать мой сайт, и я мог определить, какой пользователь, по этому сертификату.

Я уже настроил SSL в IIS, но сейчас это не то, что мне нужно, и я не знаю, с чего начать.

Как я могу добиться этого в asp.net С#?


person enb081    schedule 18.02.2013    source источник


Ответы (2)


Чтобы создать безопасный механизм аутентификации, вы должны использовать как клиентские сертификаты, так и имя пользователя/пароль. Причина в том, что сертификат — это то, что можно украсть (скопировать), а пароль — это то, что известно только человеку. Альтернативой может быть сертификат на смарт-карте, защищенный PIN-кодом.

Чтобы использовать клиентские сертификаты в приложениях ASP.NET, вам необходимо сделать следующее:

Шаг 1. В диспетчере IIS откройте свое приложение или веб-сайт, выберите «Настройки SSL» и выберите «Требовать SSL» и «Требовать сертификат клиента».

Теперь, когда пользователь открывает ваш веб-сайт, браузер предложит ему выбрать сертификат клиента, который будет использоваться при общении.

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

Шаг 2. Добавьте элемент конфигурации (web.config, базу данных и т. д.). В этот список вы должны добавить отпечатки всей цепочки ЦС (центров сертификации) для ваших клиентских сертификатов.

<add key="ClientCertificateIssuerThumbprints" value="4901f5b87d736cd88792bd5ef7caee91bf7d1a2b,0113e31aa85d7fb02740a1257f8bfa534fb8549e,c9321de6b5a82666cf6971a18a56f2d3a8675602"/>

Шаг 3. Создайте классическую страницу входа с именем пользователя и паролем. Подтвердите имя пользователя/пароль.

Шаг 4. Добавьте следующий код на страницу входа:

var x509 = new X509Certificate2(this.Request.ClientCertificate.Certificate);
var chain = new X509Chain(true);
chain.ChainPolicy.RevocationMode = X509RevocationMode.Offline;
chain.Build(x509);

var validThumbprints = new HashSet<string>(
    System.Configuration.ConfigurationManager.AppSettings["ClientCertificateIssuerThumbprints"]
        .Replace(" ", "").Split(',', ';'),
    StringComparer.OrdinalIgnoreCase);

// if the certificate is self-signed, verify itself.
for (int i = chain.ChainElements.Count > 1 ? 1 : 0; i < chain.ChainElements.Count; i++)
{
    if (!validThumbprints.Contains(chain.ChainElements[i].Certificate.Thumbprint))
        throw new UnauthorizedAccessException("The client certificate selected is not authorized for this system. Please restart the browser and pick the certificate issued by XXXXX");
}

// certificate Subject would contain some identifier of the user (an ID number, SIN number or anything else unique). here it is assumed that it contains the login name and nothing else
if (!string.Equals("CN=" + login, x509.Subject, StringComparison.OrdinalIgnoreCase))
    throw new UnauthorizedAccessException("The client certificate selected is authorized for another user. Please restart the browser and pick another certificate.");

Только когда и пароль, и сертификат проверены, пользователь должен быть допущен в систему.

person Knaģis    schedule 05.03.2013
comment
Какой смысл в сертификате, если клиент может его экспортировать и установить куда захочет? Имя пользователя/пароль гарантирует мне подлинность пользователя, но мне также необходимо убедиться в подлинности машины. - person enb081; 06.03.2013
comment
Можно установить сертификат, чтобы закрытые ключи (необходимые для аутентификации) нельзя было экспортировать. Некоторые ноутбуки позволяют устанавливать сертификаты в аппаратный чип. Альтернативой может быть хранение сертификата на смарт-карте. - person Knaģis; 06.03.2013
comment
Если сертификата клиента вам достаточно, вы используете его для аутентификации: iis. сеть/configreference/system.webserver/security/ - person flup; 09.03.2013
comment
Я согласен, я тоже хочу аутентифицировать рабочую станцию. Но я думаю, что решение для меня будет состоять в том, чтобы использовать клиентские сертификаты «один (частный) для многих» и генерировать каждый из клиентских сертификатов с метаданными для идентификации рабочей станции (и метаданные должны быть зашифрованы для дополнительной безопасности ). - person TheLegendaryCopyCoder; 09.01.2017
comment
Можно ли аутентифицировать пользователя по сертификату, но без указания логина и пароля? Пользователь просто использует смарт-карту с сертификатом, и система автоматически войдет в систему? - person Eru; 15.12.2020

Предполагая, что у вас есть IIS 7.0 или выше, вы можете настроить аутентификацию сопоставления сертификатов клиентов.

Использование Active Directory (чрезвычайно просто, возложение работы по сопоставлению на сервер AD)

<location path="Default Web Site">
   <system.webServer>
      <security>
         <access sslFlags="Ssl, SslNegotiateCert" />
          <authentication>
            <windowsAuthentication enabled="false" />
            <anonymousAuthentication enabled="false" />
            <digestAuthentication enabled="false" />
            <basicAuthentication enabled="false" />
            <clientCertificateMappingAuthentication enabled="true" />
         </authentication>
     </security>
   </system.webServer>
</location>

Или используя IIS (в IIS требуется дополнительная настройка, требуется доступ к сертификату клиента, но работает автономно, без обращения к AD). В этом случае вы указываете (один или несколько) учетных данных пользователя и

  • сопоставьте каждого пользователя с открытым ключом сертификата с пользователем, чьи учетные данные вы указываете, или
  • сопоставить несколько сертификатов пользователю на основе значений в полях сертификата

Конфигурация (многие к одному):

<location path="Default Web Site">
   <system.webServer>
      <security>
         <authentication>
            <windowsAuthentication enabled="false" />
            <anonymousAuthentication enabled="false" />
            <digestAuthentication enabled="false" />
            <basicAuthentication enabled="false" />
            <iisClientCertificateMappingAuthentication enabled="true"
                  manyToOneCertificateMappingsEnabled="true">
               <manyToOneMappings>
                  <add name="Contoso Employees"
                        enabled="true"
                        permissionMode="Allow"
                        userName="Username"
                        password="[enc:AesProvider:57686f6120447564652c2049495320526f636b73:enc]">
                     <rules>
                        <add certificateField="Subject"
                           certificateSubField="O"
                           matchCriteria="Contoso"
                           compareCaseSensitive="true" />
                     </rules>
                  </add>
               </manyToOneMappings>
            </iisClientCertificateMappingAuthentication>
         </authentication>
         <access sslFlags="Ssl, SslNegotiateCert" />
      </security>
   </system.webServer>
</location>

(Пример конфигурации довольно бесстыдно скопирован из примеров на страницах документации iis.net, которые довольно сложны.)

Или вы можете настроить свое приложение на использование проверки подлинности на основе утверждений со службой маркеров безопасности (STS). который аутентифицирует клиентов на основе клиентских сертификатов. ADFS 2.0 может выполнять эту роль, а если она недоступна, вы можете обратиться к Thinktecture Identity Server.

person flup    schedule 11.03.2013
comment
что-нибудь новое для ядра AspNet 2.0? - person Vikas Rana; 20.03.2018
comment
как мы можем сделать это в .net core 2.x? - person Ask; 02.08.2018