繁体   English   中英

C# .net core 2.1 授权的异常处理

[英]C# .net core 2.1 Exception handling of Authorization

因此,在 .net framework 4.7.1 中的 Web API 2 中,如果您有一个处理异常的过滤器,定义如下:

public sealed class RequestExceptionFilter : ExceptionFilterAttribute..

在 WebApiConfig 中:

config.Filters.Add(new MyAuthorizationFilter());
config.Filters.Add(new RequestExceptionFilter());

如果MyAuthorizationFilter发生任何异常,它将在RequestExceptionFilter被捕获。

在 .net core 2.1 中,我有以下内容:

services.AddMvc(options =>
{
    options.Filters.Add(new MyExceptionFilter());

}).SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddAuthentication("Basic").AddScheme<AuthenticationSchemeOptions, UserAuthenticator>("Basic", null)

// configure DI for application services
services.AddScoped<IUserAuthenticator, UserAuthenticatorHandler>();

我有以下处理程序:

public sealed class UserAuthenticator: AuthenticationHandler<AuthenticationSchemeOptions>

现在,如果我在作为UserAuthenticator方法的protected override async Task<AuthenticateResult> HandleAuthenticateAsync()抛出异常,则服务器返回内部服务器错误并跳过异常处理。

我可以让它传播到异常过滤器吗?

根据https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/filters?view=aspnetcore-2.1似乎授权过滤器在异常过滤器之前运行。

也许如果您将异常处理从过滤器移到要添加为中间件

public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)方法中: app.UseMiddleware<MyErrorHandling>();

public class MyErrorHandling
{
    private readonly RequestDelegate _next;

    public MyErrorHandling(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        try
        {
            await _next.Invoke(context);
        }
        catch (Exception e)
        {
            // Do stuff?
            await context.Response.WriteAsync("it broke. :(");
        }
    }
}

我认为这种方法比使用过滤器更灵活。

创建这样的扩展方法

public static void UseGlobalExceptionHandler(this IApplicationBuilder appBuilder, ILogger logger)
        {
            appBuilder.UseExceptionHandler(app =>
            {
                app.Run(async context =>
                {
                    context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
                    context.Response.ContentType = "application/json";

                    var ex = context.Features.Get<IExceptionHandlerFeature>()?.Error;
                    //AuthException is your custom exception class
                    if (ex != null && ex.GetType() == typeof(AuthException))
                    {
                        context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
                        context.Response.ContentType = "application/json";
                        await context.Response.WriteAsync("Unautherized");
                    }
                });
            });
        }

在配置方法下的 startup.cs 文件中使用它

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
   //Use it like this
   app.UseGlobalExceptionHandler();
}

在 .net core 中,过滤器(尤其是全局过滤器)的许多功能已被中间件取代。

MVC 中过滤器的执行顺序由框架固定 - MSDN 链接

在 .net core 中,中间件按照配置中的顺序执行

Startup.cs Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)方法

这意味着如果您的中间件中存在异常,您的授权过滤器将不起作用。 解决此问题的最佳方法是将您的异常处理移动到中间件中,并确保在该方法中首先或几乎首先添加它。

另一种选择是启用开发人员异常页面进行测试。

我已经在这个 SO answer 中更详细地回答了如何How to catch an exception and response with a status code in .NET Core

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM