.NET Core Web Api return 来自中间件的用户未经授权的代码

.NET Core WebApi return Unathorized code to user from middleware

我想在中间件出现问题时向用户发送错误请求代码。

我的 Startup.cs 看起来像这样:

// configure method 
                                                                                                         
if (env.IsDevelopment())                                                                                 
{                                                                                                        
    app.UseDeveloperExceptionPage();                                                                     
}                                                                                                        
                                                                                                                                                                                   
app.UseCors("CorsPolicy");                                                                               
app.UseMiddleware<RequestMiddleware>();                                                                  
app.UseMiddleware<SecondRequestMiddleware>();                                                                                                                                                    
app.UseRouting();                                                                                        
                                                                                                         
app.UseEndpoints(endpoints =>                                                                            
{                                                                                                        
    endpoints.MapControllers();                                                                                                                                           
});         

我的中间件是这样的:

public class RequestMiddleware                                                                                                                     
{                                                                                                                                                  
    private readonly RequestDelegate _next;                                                                                                        
                                                                                                                                                   
    public RequestMiddleware(RequestDelegate next)                                                                                                 
    {                                                                                                                                              
        _next = next;                                                                                                                              
    }                                                                                                                                              
                                                                                                                                                   
    public async Task InvokeAsync(HttpContext context, IAuthInfoService authInfoService, IPowiadomieniaCacheService cacheService)                  
    {                                                                                                                                              
        string jwt = context.Request.Headers["custom_header"];                                                                                
        if (string.IsNullOrEmpty(jwt))                                                                                                             
        {
            // no jwt in headers so i want to return Unauthorized to user:
            await ReturnErrorResponse(HttpContext context);                      
        }                                                                                                                                          
    }                                                                                                                                              
                                                                                                                                                   
    private Task ReturnErrorResponse(HttpContext context)                                                                                          
    {                                                                                                                                              
        context.Response.ContentType = "application/json";                                                                                         
        context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;                                                                            
                                                                                                                                                   
        return Task.CompletedTask;                                                                                                                 
    }                                                                                                                                              
                                                                                                                                                                                                                                                                                       
}                                                                                                                                                  

但我仍然进入我的 SecondRequestMiddleware。我想 return 401 Stauts Code 给用户,当 headers 中没有 jwt 时(这就是我的 RequestMiddleware 检查的内容)并停止处理此请求。

如何在中间件中验证请求,如果条件通过,return 错误代码/对用户的响应?

您可以像这样修改您的中间件以短路请求。 其中 await context.Response.StartAsync(); 将开始响应并且不会继续进行。

public class RequestMiddleware
{
    private readonly RequestDelegate _next;
    public RequestMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context, IAuthInfoService authInfoService, IPowiadomieniaCacheService cacheService)
    {
        string jwt = context.Request.Headers["custom_header"];
        if (string.IsNullOrEmpty(jwt))
        {
            // no jwt in headers so i want to return Unauthorized to user:
            await ReturnErrorResponse(HttpContext context);
        }
        else
        {
            await _next(context);
        }
    }

    private async Task ReturnErrorResponse(HttpContext context)
    {
        context.Response.ContentType = "application/json";
        context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
        await context.Response.StartAsync();
    }
}

when there is no jwt in headers (thats what my RequestMiddleware checks) and stopped processing this request.

您可以终止请求 写以下内容:

await context.Response.WriteAsync("error message");

如果headers中有jwt,那么需要通过下面的语句触发下面的中间件,否则不会自动执行:

 await _next.Invoke(context);

更多详情,请参考ASP.NET Core Middleware

如下更改您的 RequestMiddleware:

 public class RequestMiddleware
    {
        private readonly RequestDelegate _next;

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

        public async Task InvokeAsync(HttpContext context)
        {
            string jwt = context.Request.Headers["custom_header"];
            if (string.IsNullOrEmpty(jwt))
            { 
                await ReturnErrorResponse(context);
            }
            else
            {
                await _next.Invoke(context);// call next middleware
            }
        }

        private async Task ReturnErrorResponse(HttpContext context)
        {
            context.Response.ContentType = "application/json";
            context.Response.StatusCode = (int)HttpStatusCode.Unauthorized; 
            await context.Response.WriteAsync("error message!"); 
        }

    }