Реализация проверки подлинности сертификата в ASP. NET Core 3.1 - PullRequest
0 голосов
/ 01 марта 2020

Я создаю небольшую функцию в ASP. NET Проверка подлинности основного сертификата, как указано в официальных документах .

Примечание: Я не строю API, я просто пытаюсь защитить некоторые методы Action некоторых контроллеров, чтобы эти защищенные методы действия открывались только тогда, когда клиент имеет сертификат клиента.

На рисунке ниже показано, что я могу защитить метод Index action , для которого теперь требуется сертификат клиента. Другой метод действия, который является Конфиденциальностью, не требует сертификата клиента. В результате действие Index открывается в браузере (получена ошибка 403), но в браузере открывается действие Privacy

enter image description here

Полные коды

1. Program.cs

public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
    .ConfigureWebHostDefaults(webBuilder =>
    {
        webBuilder.UseStartup<Startup>();
        webBuilder.ConfigureKestrel(o =>
        {
            o.ConfigureHttpsDefaults(o =>
                o.ClientCertificateMode =
                    ClientCertificateMode.RequireCertificate);
        });
    });

2. Startup.cs

public Startup(IConfiguration configuration)
{
    Configuration = configuration;
}

public IConfiguration Configuration { get; }

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();
    services.AddAuthentication(
        CertificateAuthenticationDefaults.AuthenticationScheme)
        .AddCertificate(options =>
        {
            options.Events = new CertificateAuthenticationEvents
            {
                OnCertificateValidated = context =>
                {
                    var validationService = context.HttpContext.RequestServices.GetService<MyCertificateValidationService>();

                    if (validationService.ValidateCertificate(context.ClientCertificate))
                    {
                        context.Success();
                    }
                    else
                    {
                        context.Fail("invalid cert");
                    }

                    return Task.CompletedTask;
                },
                OnAuthenticationFailed = context =>
                {
                    context.Fail("invalid cert");
                    return Task.CompletedTask;
                }
            };
        });
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseCertificateForwarding();
    app.UseAuthentication();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");
    });
}

3. MyCertificateValidationService.cs

public class MyCertificateValidationService
{
    public bool ValidateCertificate(X509Certificate2 clientCertificate)
    {
        var cert = new X509Certificate2(Path.Combine("localhost_root_l1.pfx"), "1234");
        if (clientCertificate.Thumbprint == cert.Thumbprint)
        {
            return true;
        }

        return false;
    }
}

4. Методы действий, которые являются защищенными и незащищенными

[Authorize]
public IActionResult Index()
{
    return View();
}

public IActionResult Privacy()
{
    return View();
}

Примечание : метод действия индекса требует аутентификации клиента, тогда как для конфиденциальности не требуется сертификат клиента.

Проблемы: Проблемы, с которыми я сталкиваюсь:

  1. CertificateAuthenticationEvents & OnAuthenticationFailed, расположенный в ConfigureServices() методе файла startup.cs Я не звонила. Я проверил их, установив точки останова, но точка останова не достигнута.

  2. MyCertificateValidationService.cs class ValidateCertificate() метод также не вызывается. Я также проверил это с точкой останова

Пожалуйста, помогите мне реализовать авторизацию сертификата.

Обновление

Я создал 2 сертификата в C#, как объяснено в этом уроке 1079 *. Это:

  1. Root сертификат с именем root_localhost.pfx
  2. Сертификат клиента с именем client.pfx

Я сделал 2 вещи с этими сертификаты:

а. Я добавил root_localhost.pfx в доверенные Root центры сертификации (на Windows) для локального компьютера (используя CertManager).

b. Я импортировал сертификат клиента в браузере chrome.

Затем я выбрал проект в VS 2019 (консоль) вместо 'IIS Express' и запустил свой проект. Я открыл URL-адрес веб-сайта в окне инкогнито, URL-адрес: https://localhost: 5001

Chrome просит выбрать сертификат, см. Изображение ниже: enter image description here

При выборе я получаю Этот сайт не доступен - ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY , см. Изображение ниже:

enter image description here

Почему это происходит ????

Ответы [ 2 ]

0 голосов
/ 07 апреля 2020
options.RevocationMode = X509RevocationMode.NoCheck

установка у меня сработала

0 голосов
/ 02 марта 2020

В данный момент ваше приложение не настроено на использование клиентских сертификатов. Причина в том, что вы запускаете (размещаете) свое приложение в IIS Express. Есть 2 варианта:

1) Самый простой вариант - переключиться в режим Project (приложение будет запущено в окне консоли). Вы также можете запустить его вручную в консоли.

2) Немного более сложный метод - настроить IIS Express для работы с клиентскими сертификатами. Выполните следующие действия: 2.1) отредактируйте файл \ config \ applicationhost.config и измените раздел ниже (изменения - «Запретить»).

      <sectionGroup name="security">
        <section name="access" overrideModeDefault="**Allow**" />
        <section name="applicationDependencies" overrideModeDefault="Deny" />
        <sectionGroup name="authentication">
          <section name="anonymousAuthentication" overrideModeDefault="**Allow**" />

2.2) в вашем проекте добавьте следующий файл web.config

<configuration>
    <system.webServer>
        <security>
            <access sslFlags="Ssl,SslNegotiateCert,SslRequireCert" />
          <authentication>
            <anonymousAuthentication enabled="true" />
          </authentication>
        </security>
    </system.webServer>
</configuration>

Далее:

Предварительные условия для работы аутентификации клиента - наличие сертификат клиента. Вы можете создать самозаверяющий сертификат, используя следующие команды или любые другие методы для создания клиентских сертификатов:

#create key
openssl req -newkey rsa:4096 -keyout key.pem -out csr.pem -nodes -days 365 -subj "/CN=Your name"
#create certificate
openssl x509 -req -in csr.pem -signkey key.pem -out cert.pem -days 365
#self sign it
openssl pkcs12 -export -in cert.pem -inkey key.pem -out your_cert.p12

Поскольку этот сертификат является самоподписанным, его необходимо добавить в доверенные Root центры сертификации (включено Windows) для локального компьютера (с использованием CertManager).

После этого вам необходимо установить его (импортировать) в хранилище личных сертификатов, используя тот же CertManager, но только для текущего пользователя. Альтернативные способы - использовать настройки Chrome («Управление сертификатами»). Это необходимо для Chrome, чтобы иметь возможность отправлять сертификат на сервер.

Также в вашем приложении вы можете изменить эту опцию, которая разрешает самозаверяющие сертификаты.

            services.AddAuthentication(
                    CertificateAuthenticationDefaults.AuthenticationScheme)
                    .AddCertificate(options => 
                    { 
                        **options.AllowedCertificateTypes = CertificateTypes.All**;

В конце концов эти изменения должны запрашивать выбор сертификата при доступе к сайту.

Совет: Вас могут не попросить выбрать, какой сертификат использовать, если вы снова посещаете ту же страницу, пока не закроете все экземпляры chrome. , если вы хотите, чтобы он спросил, какой сертификат использовать, откройте новое окно инкогнито.

...