2017-08-15 96 views
15

我使用API​​制作网站时,API需要验证,因此用户只能获取自己的数据。我已经编写了以下中间件来验证登录。.net-core中间件返回空白结果

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的配置方法相关的代码

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?}"); 
     }); 
    } 

我怎样才能让我的中间件返回一个空白页,状态码?

请解释downvoting的原因,以便我可以改善问题,并知道我做错了什么。

更新

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

context.Response.StatusCode = 401; //UnAuthorized 

它能正常工作,用户获得给出的消息:

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

Howerver我不希望用户在登录失败时获得200状态码,而是获得401状态码。但是,当使用状态码行时,用户将被重定向。那么我怎样才能发送状态码而不用重定向呢?

+0

为什么不使用'Authorize'属性 – CodeNotFound

+0

授权假定在用户登录(经由饼干如果即时通讯正确)进出口制造用于移动应用的API,因此该应用将它需要从一个有效的用户的请求。如果没有登录,授权将重定向到注册页面,这不是我想要的API行为。 –

+0

我会看看OpenId中间件。这个中间件使用授权属性 –

回答

4

我有一个预感,app.UseIdentity()有默认的行为,当403/401发生时,它会拦截响应并启动重定向。尝试评论一下,看看它是否有效。

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

最新的留言:我强烈建议不传递凭据为每个请求。我建议使用预构建的auth提供程序并将其作为中间件实现。 Authorize属性应该足以满足请求,并且可以执行您正在查找的内容。如果你确实想要返回一些特殊的东西,你可以用中间件覆盖响应,例如app.UseIdentity()中间件可能会重定向。

0

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

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