我有一个相对简单的 ASP.NET Core MVC Intranet 应用程序,最初是用 .NET Core 2.0 编写的,但我正在尝试将其更新到 .NET 8。
我还没有对其进行任何其他更改,我现在所做的就是尝试让它在 .NET 8 中工作。该应用程序使用集成 Windows 身份验证以及
Authorize
属性和 Roles 属性实施一些基本授权。
此代码应该将收到 403 响应的用户重定向到我的
AccessDenied
页面,它适用于 .NET Core 2.0,但不适用于 .NET 8。此代码最初位于我的 Startup
类中,但我已将其移至 .NET 8 的 Program
类,因为我觉得这似乎是我现在应该做的事情。
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
重定向定义使用了错误的顺序。
您必须将其放置在
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();
}
}
使用中间件:
或者,如果您想使用中间件,在这种情况下,您可以尝试如下:
公共类AccessDeniedMiddleware { 私有只读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();