Реализовать два варианта аутентификации (токен и сертификат) в ASP Net Core - PullRequest
1 голос
/ 19 июня 2020

[Target netcoreapp3.1]

Привет! Итак, у меня есть этот веб-API, который защищен промежуточным программным обеспечением этой формы в моем Startup.cs:


public void ConfigureServices(IServiceCollection services)
{
    //other services configuration
    services.AddProtectedWebApi(options => { /* config */};
    //other services configuration
}

Это проверяет токены Jwt, выпущенные Azure, и предоставляет доступ к API; работает нормально. В настоящее время у меня есть клиентский веб-сайт angular, на котором пользователь входит через Azure AD. Angular отправляет токен моему веб-API, и все работает.

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

Есть ли простой способ использовать в этом случае два варианта аутентификации без необходимости создавать отдельное веб-приложение? Я немного читал там: https://docs.microsoft.com/en-us/aspnet/core/security/authentication/certauth?view=aspnetcore-3.1#optional -client-Certific Но, похоже, он работает только с предварительным просмотром ASP. NET Core 5, который я не могу использовать в своей ситуации .

1 Ответ

0 голосов
/ 19 июня 2020

Надеюсь, что последующее кому-то поможет! В конце концов я нашел эту ссылку: https://docs.microsoft.com/en-us/aspnet/core/security/authorization/limitingidentitybyscheme?view=aspnetcore-3.1

В ней объясняется, как реализовать несколько политик авторизации, которые обе имеют шанс на успех. Ниже приведено решение, которое я нашел с помощью IIS после небольшого дополнительного исследования:

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    //other services configuration
services.Configure<IISOptions>(options =>
            {
                options.ForwardClientCertificate = true;
            });

            services.Configure<CertificateForwardingOptions>(options =>
            {
                options.CertificateHeader = {/*your header present in client request*/};
            });
    //other services configuration
services.AddAuthentication(CertificateAuthenticationDefaults.AuthenticationScheme)
.AddCertificate(options =>
            {
                options.AllowedCertificateTypes =/*Whatever you need*/;
                options.Events = new CertificateAuthenticationEvents
                {
                    OnCertificateValidated = context =>
                    {

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

                        return Task.CompletedTask;
                    }
                };
            });


    services.AddProtectedWebApi(options => { /* config */};
    //other services configuration
}

{CertValidationClass} является сервисом или вспомогательным классом, специально созданным для проверить все, что мне нужно проверить, чтобы утвердить сертификат. Очевидно, вы можете добавить в этот шаблон гораздо больше проверок и действий по своему усмотрению.

У меня уже было app.UseAuthentication(); app.UseAuthorization(); в моем конвейере промежуточного программного обеспечения, нет необходимости менять это, но вам нужно добавить app.UseCertificateForwarding(); перед эти два.

Теперь мне просто нужно было указать над контроллером, который я хотел защитить, что я хотел использовать оба метода авторизации, и точно так же, если один из них выходит из строя, он возвращается к другому, и он отлично работает , Я тестировал, отправляя запросы через Insomnia с / без токенов и с / без сертификатов.

MyApiController.cs

[Authorize(AuthenticationSchemes = AuthSchemes)]
    public class MyApiController
    {
        //Just add the schemes you want used here
        private const string AuthSchemes =
            CertificateAuthenticationDefaults.AuthenticationScheme; + "," +
            JwtBearerDefaults.AuthenticationScheme;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...