Пользовательская ASP.NET Основная проверка подлинности файлов cookie

#asp.net #.net #asp.net-web-api #asp.net-core #.net-core

#asp.net #.net #asp.net-web-api #asp.net-core #.net-core

Вопрос:

Я провел последние несколько дней, играя с аутентификацией для своей службы в ASP.NET Ядро. Мое приложение имеет простую систему токенов аутентификации. Ожидается, что в запросе содержится файл cookie, я беру этот файл cookie и отправляю запрос на свой сервер аутентификации. Сервер аутентификации возвращает мне права пользователя. Если файл cookie не существует или запрос аутентификации возвращается с ошибкой, приложение должно выдать 401. В случае успеха он перейдет к следующей части конвейера и проверит авторизацию на правах.

Я настроил свое промежуточное программное обеспечение аутентификации, как и следовало ожидать, — наследование от AuthenticationHandler, AuthenticationMiddleware и т. Д. Мой пользовательский обработчик аутентификации наследуется от Authenticationhandler и перезаписывает HandleAuthenticateAsync() . Этот метод использует предоставленный пользователем файл cookie для получения пользовательских данных, создания моего ClaimsPrincipal и либо возвращает AuthenticateResult .Успех или ошибка аутентификации.

Когда AuthenticationResult.Сбой возвращает, я полагал, что приложение завершит работу, но мое приложение все равно перейдет к следующей части конвейера (app.UseMvc()), когда я думал, что оно вернет ошибку 401.

Мой Startup.cs выглядит следующим образом.

 public class Startup
{
    public Startup(IHostingEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
            .AddEnvironmentVariables();
        Configuration = builder.Build();
    }

    public IConfigurationRoot Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddAuthentication();
        services.AddMvc();
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole(Configuration.GetSection("Logging"));
        loggerFactory.AddDebug();

        app.UseCustomAuthentication(new CustomAuthenticationOptions()
        {
            AutomaticChallenge = true,
            AutomaticAuthenticate = true
        });

        app.UseMvc();
    }
}
  

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

         services.AddMvc(config =>
        {
            var policy = new AuthorizationPolicyBuilder()
                             .RequireAuthenticatedUser()
                             .Build();
            config.Filters.Add(new AuthorizeFilter(policy));
        });
  

Так ли это должно быть настроено? При сбое аутентификации не следует ли завершить работу конвейера?

Ответ №1:

При сбое аутентификации не следует ли завершить работу конвейера?

Предположим, у вас есть другое промежуточное программное обеспечение для проверки подлинности:

     app.UseCustomAuthentication(new CustomAuthenticationOptions()
    {
        AutomaticChallenge = true,
        AutomaticAuthenticate = true
    });
    app.UseOtherAuthentication(new OtherAuthenticationOptions()
    {
        AutomaticChallenge = true,
        AutomaticAuthenticate = true
    });
  

Если конвейер завершается при сбое первой проверки подлинности, другое промежуточное программное обеспечение аутентификации никогда не запускается. Это было бы менее расширяемым.

Другой момент, предположим, вы хотите разрешить какое-либо действие для анонимного запроса с использованием AllowAnonymous атрибута. Как вы разрешаете?

Даже если промежуточное программное обеспечение аутентификации завершается с ошибкой, без вызова HttpContext.Authentication.ChallengeAsync() или использования Authorize атрибута сервер не отвечает 401, 403 или 302.

Насколько я знаю, это ожидаемое поведение, и встроенная проверка подлинности cookie работает так же. Если вы хотите сначала принудительно аутентифицировать пользователя, вам нужно добавить его глобально (как вы это делаете) или использовать Authorize атрибут поверх контроллера.