.net-core 中间件 return 空白结果

.net-core middleware return blank result

我正在制作一个带有 API 的网站,API 需要验证,因此用户只能获得他自己的数据。我编写了以下中间件来验证登录。

public class ApiAuthenticationMiddleware
{
    private readonly RequestDelegate _next;
    private readonly UserManager<ApplicationUser> _userManager;
    private readonly SignInManager<ApplicationUser> _signInManager;

    public ApiAuthenticationMiddleware(RequestDelegate next,
        SignInManager<ApplicationUser> signInManager,
        UserManager<ApplicationUser> usermanager)
    {
        _next = next;
        _signInManager = signInManager;
        _userManager = usermanager;
    }

    public async  Task Invoke(HttpContext context)
    {
        if (!context.Request.Query.ContainsKey("password") || !context.Request.Query.ContainsKey("email"))
        {
            context.Response.StatusCode = 401; //UnAuthorized
            await context.Response.WriteAsync("Invalid User Key");
            return;
        }
        var email = context.Request.Query["email"];
        var password = context.Request.Query["password"];

        var result = await _signInManager.PasswordSignInAsync(email, password, false, lockoutOnFailure: false);
        if (result.Succeeded)
        {
            await _next.Invoke(context);
        }
        else if (//some more checks)
            context.Response.StatusCode = 401; //UnAuthorized
            await context.Response.WriteAsync("Invalid User Key");
            return;
        }
    }
}

我想要的是,如果用户没有有效登录,则显示一个空白页面或类似 "Invalid User Key" 的错误消息。然而,目前发生的是主页被 returned(因为我的中间件在 usemvc 之前被调用并且 return 语句跳过了 usemvc 完成的控制器请求)。

我的相关代码在startup.cs

中的configure方法
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {

        app.UseIdentity();
        app.UseWhen(x => (x.Request.Path.StartsWithSegments("/api", StringComparison.OrdinalIgnoreCase)),
            builder =>
            {
                builder.UseMiddleware<ApiAuthenticationMiddleware>();
            });
        app.UseStaticFiles();
        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
    }

如何使我的中间件 return 成为带有状态代码的空白页面?

更新

在尝试了很多之后我发现当我删除:

 context.Response.StatusCode = 401; //UnAuthorized

它按预期工作,用户收到消息:

await context.Response.WriteAsync("Invalid User Key"); 

但是我不希望用户在登录失败时获得 200 状态码,而是 401 状态码。但是当使用 statuscode 行时,用户被重定向。那么如何在不重定向的情况下发送状态码呢?

我有一种预感,app.UseIdentity() 有默认行为,当出现 403/401 时,它将拦截响应并启动重定向。尝试将其注释掉,看看是否有效。

替代解决方案参见:

最后评论:我强烈建议不要为每个请求传递凭据。我建议使用预构建的身份验证提供程序并将其实现为您的中间件。 Authorize 属性应该足以满足所发出的请求,并且可以满足您的需求。如果您确实想要 return 一些特别的东西,您可以使用中间件覆盖响应,例如 app.UseIdentity() 中间件可能与重定向有关。

在设置 StatusCode 之前尝试使用 .Clear() 。

            context.Response.Clear();
            context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
            await context.Response.WriteAsync("Unauthorized");

您还应该设置 ContentType。 像这样:

        context.Response.ContentType = "text/plain";
        context.Response.StatusCode = 401; //UnAuthorized
        await context.Response.WriteAsync("Invalid User Key");