.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");
我正在制作一个带有 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");