Я пытаюсь создать собственную политику авторизации для 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
{
// ....
}
Я ожидаю, что требование оценит и потерпит неудачу. Но код никогда не достигается, и требование всегда выполняется успешно, страница загружается нормально, независимо от того, что я пытаюсь сделать. Что мне не хватает?
Я ожидаю, что требование оценит и потерпит неудачу. Но код никогда не достигалось, и требование всегда выполняется успешно, страница загружается просто отлично, независимо от того, что я пытаюсь. Что мне не хватает?
На основе вашего общего фрагмента кода и сценария я попытался устранить неполадки в вашей реализации.
Согласно моему расследованию, похоже, что вы правильно настроили большинство компонентов.
Я попробовал ваш код и кажется 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() отменял мое требование аутентификации, хотя код был правильным.