如何在 ASP.NET Core 2 中抛出 ForbiddenException 而不是使用 AccessDeniedPath

How to throw ForbiddenException in ASP.NET Core 2 Instead of using AccessDeniedPath

我正在开发 ASP.NET Core 2 Web 应用程序。我正在处理 [授权(角色或策略)] 页面的拒绝访问页面。

默认情况下,ASP.NET Core 2.0 不会显示原始 URL 并返回 403 状态,而是将请求重定向到状态为302 -> 这不是我想要的。

而不是重定向 AccessDenied 页面。我想要 ASP.NET Core 抛出我自定义的 ForbiddenException 异常,这样我就可以像处理未处理的异常一样处理未经授权的访问。

这是我的身份验证配置:

services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme; // Cookies
    options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; // Cookies       
    options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme; // Cookies
})
.AddCookie(options => {

    options.LoginPath = "/Auth/Login/";
    options.LogoutPath = "/Auth/Logout/";

    // I want disable this and throw ForbiddenException instead.
    options.AccessDeniedPath = "/Auth/AccessDenied/";  
});

有人帮忙吗?谢谢!

重定向到 AccessDeniedPath 的代码由 CookieAuthenticationEvents.OnRedirectToAccessDenied 处理,为了完整性包含在此处:

public Func<RedirectContext<CookieAuthenticationOptions>, Task> OnRedirectToAccessDenied { get; set; } = context =>
{
    if (IsAjaxRequest(context.Request))
    {
        context.Response.Headers["Location"] = context.RedirectUri;
        context.Response.StatusCode = 403;
    }
    else
    {
        context.Response.Redirect(context.RedirectUri);
    }
    return Task.CompletedTask;
};

为了覆盖此行为,您可以提供自己的 OnRedirectToAccessDenied 实现,它可以写入响应,或者在您的情况下抛出异常。为此,您可以使用如下内容:

services.AddAuthentication(...)
    .AddCookie(options => {
        // ...
        options.Events.OnRedirectToAccessDenied = context => {
            // Your code here.
            // e.g.
            throw new YouAreNotWelcomeHereException();
        };
    });

这里,contextRedirectContext 的一个实例,它(通过其继承树)包含如下属性:

使用这些属性,您可以获得有关传入请求的任何信息。也可以自己写回复等