У меня есть относительно простое приложение для интрасети ASP.NET Core MVC, которое изначально было написано на .NET Core 2.0, но которое я пытаюсь обновить до .NET 8.
Я не вношу в него никаких других изменений (пока), все, что я делаю сейчас, это пытаюсь заставить его работать в .NET 8. Приложение использует встроенную аутентификацию Windows вместе с атрибутом Authorize
и свойством roles для реализации некоторых базовая авторизация.
Предполагается, что этот код перенаправляет пользователей, получивших ответ 403, на мою страницу AccessDenied
, и он работает в .NET Core 2.0, но не работает в .NET 8. Этот код изначально был в моем классе Startup
, но я переместил его. это в класс Program
для .NET 8, поскольку у меня сложилось впечатление, что мне, вероятно, следует делать это сейчас.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();
builder.Services.AddAuthentication(IISDefaults.AuthenticationScheme);
var app = builder.Build();
app.UseStatusCodePages(statusCodeContext =>
{
if (statusCodeContext.HttpContext.Response.StatusCode == 403)
{
statusCodeContext.HttpContext.Response.Redirect(statusCodeContext.HttpContext.Request.PathBase + "/AccessDenied");
}
return Task.CompletedTask;
});
Насколько я могу судить, он просто полностью игнорирует метод UseStatusCodePages
. Честно говоря, я программист-любитель, поэтому мало что знаю о тонкостях ASP.NET Core MVC, поэтому я уверен, что, вероятно, скопировал этот код откуда-то в Интернете (вероятно, StackOverflow, даже ) еще в 2019 году. Я просто не могу понять, почему сейчас это не работает в .NET 8.
Я нашел другие сообщения с потенциальными решениями, но они либо включали в себя вещи, которые здесь не применимы, например, использование файлов cookie, либо они включали добавление моего собственного промежуточного программного обеспечения, которое немного выше моего понимания и кажется немного сложным для того, что раньше было относительно простой. Надеюсь, я просто упускаю что-то очевидное. Большое спасибо за Вашу помощь!
Кажется, он полностью игнорирует метод UseStatusCodePages, насколько я могу судить. Я должен быть честным, я вроде как любитель программист, поэтому я мало что знаю о тонкостях ASP.NET Core MVC, поэтому я уверен, что, вероятно, скопировал этот код где-то в Интернете. (вероятно, даже StackOverflow) еще в 2019 году. Я просто не могу понять почему сейчас это не работает в .NET 8.
Основываясь на вашем сценарии и описании, я попытался воспроизвести вашу проблему и смог найти причину, по которой вы не смогли перенаправить на страницу с отказом в доступе, пока есть error 403
Я видел, что вы используете неправильный порядок определения перенаправления UseStatusCodePages
.
Вам необходимо разместить UseStatusCodePages
между app.UseRouting();
и app.UseAuthentication();
промежуточным ПО, иначе оно всегда будет игнорироваться.
Правильный заказ:
app.UseRouting();
app.UseStatusCodePages(async context =>
{
var response = context.HttpContext.Response;
if (response.StatusCode == 403 || response.StatusCode == 401)
{
response.Redirect("/Users/AccessDenied");
}
await Task.CompletedTask;
});
app.UseAuthentication();
Действие отказа в доступе:
public class UsersController : Controller
{
[AllowAnonymous]
[HttpGet]
public IActionResult AccessDenied()
{
return View();
}
}
Использование промежуточного программного обеспечения:
В качестве альтернативы, если вы хотите использовать промежуточное программное обеспечение, в этом случае вы можете попробовать следующее:
public class AccessDeniedMiddleware
{
private readonly RequestDelegate _next;
public AccessDeniedMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context)
{
await _next(context);
if (context.Response.StatusCode == 401 || context.Response.StatusCode == 403)
{
context.Response.Redirect("/Users/AccessDenied");
}
}
}
Примечание. await _next(context);
необходимо ставить перед условием проверки контекста.
Порядок промежуточного программного обеспечения:
app.UseRouting();
app.UseMiddleware<AccessDeniedMiddleware>();
app.UseAuthentication();
Выход:
Я протестировал воспроизведение как StatusCode
401, так и 403, вы можете настроить свою логику в соответствии с вашими требованиями.
Спасибо, это было именно оно! В частности, мне пришлось добавить app.UseRouting, app.UseAuthentication и app.UseAuthorization, чтобы заставить его работать сейчас; в моей программе раньше не было ничего из этого. Это помогло, еще раз спасибо за подробный ответ
Спасибо за новости, я рад помочь вам в этом.
Итак, какое ожидаемое поведение вы пытаетесь реализовать? Также включите контроллер, чтобы я мог четко понимать, чего вы пытаетесь достичь. Насколько я понимаю, после неудачной авторизации вы хотите перенаправить с помощью 403. Это можно легко сделать, используя промежуточное программное обеспечение в ядре .NET или более поздней версии на 6.