Атрибут Authorize не может блокировать запросы в ASP.Net Core 3.0 Web API - PullRequest
0 голосов
/ 11 ноября 2019

Я пытаюсь настроить аутентификацию на основе файлов cookie, работая с проектом ASP.Net Core 3.0 Web Api.

В данный момент мои ConfigureServices выглядят так:

public void ConfigureServices(IServiceCollection services)
    {
        services.AddCors(options =>
        {
            options.AddPolicy("CorsPolicy",
                builder => builder.AllowAnyOrigin()
                .AllowAnyMethod()
                .AllowAnyHeader());
        });

        services.AddAuthentication(options => 
            {
                options.DefaultScheme = "Cookies";
            })
            .AddCookie("Cookies", options => 
            {
                options.Cookie.Name = "auth_cookie";
                options.Cookie.SameSite = SameSiteMode.None;
                options.Events = new CookieAuthenticationEvents
                {
                    OnRedirectToLogin = redirectContext =>
                    {
                        redirectContext.HttpContext.Response.StatusCode = 401;
                        return Task.CompletedTask;
                    }
                };
            });

        services.AddAuthorization();

        services.AddControllers();
    }

И мой метод Configure выглядит следующим образом:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseCors("CorsPolicy");

        app.UseHttpsRedirection();

        app.UseAuthentication();

        app.UseAuthorization();

        app.UseRouting();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers().RequireAuthorization();
        });
    }

Я применил атрибут [Microsoft.AspNetCore.Authorization.Authorize] к сгенерированному по умолчанию WeatherForecastController и перешел на соответствующую страницу. Я ожидал получить ошибку, поскольку в моем запросе не было файла cookie, однако страница загружается без проблем.

Изучая журналы отладки, я вижу следующее:

Microsoft.Extensions.Hosting.Internal.Host: Debug: Hosting started
Microsoft.AspNetCore.Hosting.Diagnostics: Information: Request starting HTTP/2.0 GET https://localhost:44376/weatherforecast  
Microsoft.AspNetCore.HostFiltering.HostFilteringMiddleware: Debug: Wildcard detected, all requests with hosts will be allowed.
***Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler: Debug: AuthenticationScheme: Cookies was not authenticated.***
Microsoft.AspNetCore.Routing.Matching.DfaMatcher: Debug: 1 candidate(s) found for the request path '/weatherforecast'
Microsoft.AspNetCore.Routing.Matching.DfaMatcher: Debug: Endpoint 'NotesApp.WebApi.Controllers.WeatherForecastController.Get (NotesApp.WebApi)' with route pattern 'WeatherForecast' is valid for the request path '/weatherforecast'
Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware: Debug: Request matched endpoint 'NotesApp.WebApi.Controllers.WeatherForecastController.Get (NotesApp.WebApi)'
Microsoft.AspNetCore.Routing.EndpointMiddleware: Information: Executing endpoint 'NotesApp.WebApi.Controllers.WeatherForecastController.Get (NotesApp.WebApi)'
Microsoft.AspNetCore.Mvc.ModelBinding.ModelBinderFactory: Debug: Registered model binder providers, in the following order: Microsoft.AspNetCore.Mvc.ModelBinding.Binders.BinderTypeModelBinderProvider, Microsoft.AspNetCore.Mvc.ModelBinding.Binders.ServicesModelBinderProvider, Microsoft.AspNetCore.Mvc.ModelBinding.Binders.BodyModelBinderProvider, Microsoft.AspNetCore.Mvc.ModelBinding.Binders.HeaderModelBinderProvider, Microsoft.AspNetCore.Mvc.ModelBinding.Binders.FloatingPointTypeModelBinderProvider, Microsoft.AspNetCore.Mvc.ModelBinding.Binders.EnumTypeModelBinderProvider, Microsoft.AspNetCore.Mvc.ModelBinding.Binders.SimpleTypeModelBinderProvider, Microsoft.AspNetCore.Mvc.ModelBinding.Binders.CancellationTokenModelBinderProvider, Microsoft.AspNetCore.Mvc.ModelBinding.Binders.ByteArrayModelBinderProvider, Microsoft.AspNetCore.Mvc.ModelBinding.Binders.FormFileModelBinderProvider, Microsoft.AspNetCore.Mvc.ModelBinding.Binders.FormCollectionModelBinderProvider, Microsoft.AspNetCore.Mvc.ModelBinding.Binders.KeyValuePairModelBinderProvider, Microsoft.AspNetCore.Mvc.ModelBinding.Binders.DictionaryModelBinderProvider, Microsoft.AspNetCore.Mvc.ModelBinding.Binders.ArrayModelBinderProvider, Microsoft.AspNetCore.Mvc.ModelBinding.Binders.CollectionModelBinderProvider, Microsoft.AspNetCore.Mvc.ModelBinding.Binders.ComplexTypeModelBinderProvider
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker: Information: Route matched with {action = "Get", controller = "WeatherForecast"}. Executing controller action with signature System.Collections.Generic.IEnumerable`1[NotesApp.WebApi.WeatherForecast] Get() on controller NotesApp.WebApi.Controllers.WeatherForecastController (NotesApp.WebApi).
***Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker: Debug: Execution plan of authorization filters (in the following order): None***
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker: Debug: Execution plan of resource filters (in the following order): None
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker: Debug: Execution plan of action filters (in the following order): Microsoft.AspNetCore.Mvc.ModelBinding.UnsupportedContentTypeFilter (Order: -3000), Microsoft.AspNetCore.Mvc.Infrastructure.ModelStateInvalidFilter (Order: -2000)
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker: Debug: Execution plan of exception filters (in the following order): None
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker: Debug: Execution plan of result filters (in the following order): Microsoft.AspNetCore.Mvc.Infrastructure.ClientErrorResultFilter (Order: -2000)
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker: Debug: Executing controller factory for controller NotesApp.WebApi.Controllers.WeatherForecastController (NotesApp.WebApi)
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker: Debug: Executed controller factory for controller NotesApp.WebApi.Controllers.WeatherForecastController (NotesApp.WebApi)
Microsoft.AspNetCore.Mvc.Infrastructure.DefaultOutputFormatterSelector: Debug: List of registered output formatters, in the following order: Microsoft.AspNetCore.Mvc.Formatters.HttpNoContentOutputFormatter, Microsoft.AspNetCore.Mvc.Formatters.StringOutputFormatter, Microsoft.AspNetCore.Mvc.Formatters.StreamOutputFormatter, Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonOutputFormatter
Microsoft.AspNetCore.Mvc.Infrastructure.DefaultOutputFormatterSelector: Debug: No information found on request to perform content negotiation.
Microsoft.AspNetCore.Mvc.Infrastructure.DefaultOutputFormatterSelector: Debug: Attempting to select an output formatter without using a content type as no explicit content types were specified for the response.
Microsoft.AspNetCore.Mvc.Infrastructure.DefaultOutputFormatterSelector: Debug: Attempting to select the first formatter in the output formatters list which can write the result.
Microsoft.AspNetCore.Mvc.Infrastructure.DefaultOutputFormatterSelector: Debug: Selected output formatter 'Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonOutputFormatter' and content type 'application/json' to write the response.
Microsoft.AspNetCore.Mvc.Infrastructure.ObjectResultExecutor: Information: Executing ObjectResult, writing value of type 'NotesApp.WebApi.WeatherForecast[]'.
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker: Information: Executed action NotesApp.WebApi.Controllers.WeatherForecastController.Get (NotesApp.WebApi) in 65.9499ms
Microsoft.AspNetCore.Routing.EndpointMiddleware: Information: Executed endpoint 'NotesApp.WebApi.Controllers.WeatherForecastController.Get (NotesApp.WebApi)'
Microsoft.AspNetCore.Hosting.Diagnostics: Information: Request finished in 182.95000000000002ms 200 application/json; charset=utf-8

Обратите внимание на две строки, которые я пометил - первая правильная указывает, что мы не прошли проверку подлинности для схемы cookie. Второй, однако, указывает, что на контроллере нет фильтров авторизации, что вызывает недоумение, потому что они есть. Вероятно, именно поэтому этот запрос разрешен.

[ApiController]
[Route("[controller]")]
[Authorize]
public class WeatherForecastController : ControllerBase
{
    private static readonly string[] Summaries = new[]
    {
        "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
    };

    private readonly ILogger<WeatherForecastController> _logger;

    public WeatherForecastController(ILogger<WeatherForecastController> logger)
    {
        _logger = logger;
    }

    [HttpGet]
    public IEnumerable<WeatherForecast> Get()
    {
        var rng = new Random();
        return Enumerable.Range(1, 5).Select(index => new WeatherForecast
        {
            Date = DateTime.Now.AddDays(index),
            TemperatureC = rng.Next(-20, 55),
            Summary = Summaries[rng.Next(Summaries.Length)]
        })
        .ToArray();
    }
}

Может ли кто-нибудь пролить свет на то, почему атрибут Authorize не обнаруживается и не выполняет действия во время выполнения?

Не могуВ данный момент я очень беспокоюсь о механизме cookie, я просто хочу, чтобы контроллер был правильно заблокирован.

Большое спасибо

Ответы [ 2 ]

1 голос
/ 12 ноября 2019

Отключив маршрутизацию конечной точки, вы фактически возвращаетесь к 2.x маршрутизации. Для решения этой проблемы вы должны убедиться, что вы используете правильный порядок построения трубопровода:

app.UseHttpsRedirection();

app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers().RequireAuthorization();
});
0 голосов
/ 11 ноября 2019

Анализируя файл журнала другого работающего проекта, я понял, что атрибут [Authorize] добавляет AuthorizeFilter из пространства имен Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter. Таким образом, приложение должно быть настроено на использование Mvc для атрибута, который должен быть обнаружен и работать должным образом.

Добавление в ConfigureServices следующего:

services.AddMvc(option => option.EnableEndpointRouting = false);

и следующего в Configure:

app.UseMvc();

все заработало.

Не совсем "очевидно", но вы идете.

...