【问题标题】:.net-core middleware return blank result.net-core 中间件返回空白结果
【发布时间】:2017-08-15 19:49:17
【问题描述】:

我正在使用 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;
        }
    }
}

我想要的是,如果用户没有有效的登录,则会显示空白页面或错误消息,例如“无效的用户密钥”。然而,此时发生的是返回主页(因为我的中间件在 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?}");
        });
    }

如何让我的中间件返回带有状态码的空白页面?

更新

在尝试了很多事情后,我发现当我删除时:

 context.Response.StatusCode = 401; //UnAuthorized

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

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

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

【问题讨论】:

  • 为什么不使用Authorize属性
  • Authorize 假设用户已登录(如果我正确,则通过 cookie)我为移动应用程序创建 API,因此应用程序发送需要来自有效用户的请求。如果未登录,授权也会重定向到注册页面,这不是我想要的 API 行为。
  • 我会看看 OpenId 中间件。此中间件与授权属性一起使用
  • @ChristianSauer 谢谢克里斯蒂安我会的,但我仍然想知道如何解决当前的问题。
  • 在每个请求中传递凭据听起来是个坏主意。我不是专家,但应该使用 cookie 身份验证或类似 OAuth2 的东西,其中传递了一个短暂的密钥。您是否尝试在响应对象中设置 ContentType 标头?

标签: c# asp.net-core middleware


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

    替代解决方案见:https://stackoverflow.com/a/43456151/3948882

    最后评论:我强烈建议不要为每个请求传递凭据。我建议使用预构建的身份验证提供程序并作为您的中间件实施。 Authorize 属性应该足以满足请求,并且可以执行您正在寻找的操作。如果您确实想返回一些特殊的东西,您可以使用中间件覆盖响应,例如 app.UseIdentity() 中间件可能带有重定向。

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        猜你喜欢
        • 2019-07-07
        • 1970-01-01
        • 2017-01-29
        • 2012-06-12
        • 1970-01-01
        • 1970-01-01
        • 2016-10-10
        • 2017-05-23
        • 1970-01-01
        相关资源
        最近更新 更多