【发布时间】: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