Пользовательский метод HandleRequirement не срабатывает

Я пытаюсь создать собственную политику авторизации для ASP.NET Core 6 MVC, но, похоже, не могу получить требование для оценки. Вот обработчик аутентификации, требование и метод HandleRequirementAsync.

Сообщение журнала в

HandleRequirementAsync ("Reached this point, evaluating requirements") 

никогда не печатается.

public class DpAuthRequirement : IAuthorizationRequirement { }

public class DpAuthHandler : AuthorizationHandler<DpAuthRequirement>
{
    private readonly ILogger<DpAuthHandler> _logger;
    private readonly site_masterContext _context;

    public DpAuthHandler(site_masterContext context, ILogger<DpAuthHandler> logger)
    {
        _context = context;
        _logger = logger;
          
        _logger.LogInformation("Created auth handler"); //this is printed in the log
    }

    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, DpAuthRequirement requirement)
    {
        _logger.LogInformation("Reached this point, evaluating requirements"); //this is NOT printed
          
        context.Fail();

        return Task.CompletedTask;
    }
}

Вот Program.cs:

public class Program
{
    public static void Main(string[] args)
    {
        var builder = WebApplication.CreateBuilder(args);

        builder.Services.AddAuthorization(options =>
            {
                options.AddPolicy("DpAuthRequirement", policy =>
                {
                    policy.Requirements.Add(new DpAuthRequirement());
                });
            });

        // cookies and session data
        builder.Services.AddDistributedMemoryCache();
 
        builder.Services.AddSession(options =>
            {
                //timeout currently set to 9 minutes
                options.IdleTimeout = TimeSpan.FromSeconds(520);
                options.Cookie.HttpOnly = true;
                options.Cookie.IsEssential = true;
            });

        var logger = LoggerFactory.Create(config =>
            {
                config.AddConsole();
                config.AddDebug();
                config.AddAzureWebAppDiagnostics();
            }).CreateLogger<Program>();

        builder.Services.AddDbContext<site_masterContext>(options => options.UseSqlServer(Environment.GetEnvironmentVariable("SQLCONNSTR_MASTER_DB")));

        builder.Services.AddScoped<site_masterContext>();
        builder.Services.AddScoped<IAuthorizationHandler, DpAuthHandler>();
        builder.Services.AddHttpContextAccessor();

        // logging
        #region LOGS
        if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") != "Production")
        {
            builder.Logging.ClearProviders();
            builder.Logging.AddConsole();
            builder.Logging.AddDebug();
            builder.Logging.AddAzureWebAppDiagnostics();
        }
        #endregion

        JwtSecurityTokenHandler.DefaultMapInboundClaims = false;

        builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
            .AddMicrosoftIdentityWebApp(builder.Configuration)
            .EnableTokenAcquisitionToCallDownstreamApi()
            .AddInMemoryTokenCaches();

        builder.Services.AddControllersWithViews(options =>
            {
                var policy = new AuthorizationPolicyBuilder()
                    .RequireAuthenticatedUser()
                    .Build();
                options.Filters.Add(new AuthorizeFilter(policy));
            }).AddMicrosoftIdentityUI();

        var app = builder.Build();

        app.UseSession();

        string pattern = "{controller=Home}/{action=Index}/{id?}";
          
        if (!app.Environment.IsDevelopment())
        {
            app.UseExceptionHandler("/Home/Error");
            app.UseHsts();

            app.MapControllerRoute(
              name: "default",
              pattern: pattern);
        }
        else
        {
            app.MapControllerRoute(
                   name: "default",
                   pattern: pattern).AllowAnonymous();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

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

        app.Run();
    }
}

И наконец, контроллер имеет следующее:

[Authorize(Policy = "DpAuthRequirement")]
public class HomeController : Controller
{
    // ....
}

Я ожидаю, что требование оценит и потерпит неудачу. Но код никогда не достигается, и требование всегда выполняется успешно, страница загружается нормально, независимо от того, что я пытаюсь сделать. Что мне не хватает?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
53
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я ожидаю, что требование оценит и потерпит неудачу. Но код никогда не достигалось, и требование всегда выполняется успешно, страница загружается просто отлично, независимо от того, что я пытаюсь. Что мне не хватает?

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

Согласно моему расследованию, похоже, что вы правильно настроили большинство компонентов.

Я попробовал ваш код и кажется HandleRequirementAsync выполнился так, как ожидалось.

Итак, я заметил, что вы использовали OpenIdConnectDefaults.AuthenticationScheme, я не уверен, правильна ли ваша конфигурация. У меня нет среды для проверки OpenIdConnectDefaults.

Поэтому я использовал builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme), который является схемой аутентификации по умолчанию.

А остальную часть кода я использовал так же, как и ваш, и мне удалось выполнить обработчик политики DpAuthRequirement.

Вот моя программа.cs:

builder.Services.AddScoped<IAuthorizationHandler, DpAuthHandler>(); builder.Services.AddHttpContextAccessor()

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("DpAuthRequirement", policy =>
    {
        policy.Requirements.Add(new DpAuthRequirement());
    });
});

//My DbConnection

/* 
 
  My Service reference DI
 
 */



builder.Services.AddScoped<IAuthorizationHandler, DpAuthHandler>();
builder.Services.AddHttpContextAccessor();

// Setting my default authentication scheme
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
            .AddCookie(options =>
            {
                options.LoginPath = "/Account/Login";
                options.AccessDeniedPath = "/Account/AccessDenied";
            });
builder.Services.AddControllersWithViews(options =>
{
    var policy = new AuthorizationPolicyBuilder()
        .RequireAuthenticatedUser()
        .Build();
    options.Filters.Add(new AuthorizeFilter(policy));
});
var app = builder.Build();

Выход:

Примечание. Я думаю, что с DpAuthRequirement проблем нет, ваш файл program.cs правильный, поэтому меня беспокоит, настроили ли вы свои OpenIdConnectDefaults соответствующим образом. Кроме того, проблема может возникнуть и с вашим условием среды (!app.Environment.IsDevelopment()), от которого я избавился во время тестирования. Я бы порекомендовал вам проверить этот официальный документ.

Спасибо за помощь! К сожалению, проблема не в OpenIdConnectDefaults, поскольку эту схему можно использовать с единым входом Azure. Однако ваше подтверждение было очень полезным. Проблема оказалась в самой моей среде UAT, где у меня случайно был установлен флаг IsDevelopment. Таким образом, вызов AllowAnonymous() отменял мое требование аутентификации, хотя код был правильным.

Geborren 12.07.2024 00:42

Да, я тоже избавился от этой части. Поэтому я рад, что ваша проблема решена.

Md Farid Uddin Kiron 12.07.2024 03:18

Другие вопросы по теме