我们在ASP Core MVC应用程序中“包装”了一个javascript应用程序。来自javascript应用程序的每个AJAX请求都会命中一个装饰有[Authorize](授权)的控制器。
在我们的启动方法中,我们定义了一个指向我们的Identity Server的AuhenticationScheme。然后还有另一种方案,用于最终将它们作为cookie登录的cookie。
为了确保所有进入的请求都经过身份验证,我们使用以下命令:
app.Use(async (context, next) =>
{
if (!context.User.Identity.IsAuthenticated)
{
string auth = context.Request.Headers["Authorization"];
if (string.IsNullOrEmpty(auth) || !auth.StartsWith("Bearer ", System.StringComparison.OrdinalIgnoreCase))
{
await context.ChallengeAsync("oidce", new AuthenticationProperties {
RedirectUri = "/"
});
}
else
{
await next();
}
}
else
{
await next();
}
});
现在,如果cookie过期,它将触发“ ChallengeAsync”-如果该调用源自浏览器发出的AJAX请求,则该操作实际上不起作用。我想,因为我在这里有了上下文,所以它只会覆盖AJAX并使浏览器开始往返。
是否可以对浏览器说“不,这不是AJAX响应,请告诉我要去的地方”?
答案 0 :(得分:0)
正如曾在评论中指出的,我几乎对这封信执行了。
app.Use(async (context, next) =>
{
if (!context.User.Identity.IsAuthenticated)
{
if (context.Request.Headers["X-Requested-With"] == "XMLHttpRequest")
{
// webapp will then do a location.reload() which triggers the auth
context.Response.StatusCode = 401;
}
else
{
string auth = context.Request.Headers["Authorization"];
if (string.IsNullOrEmpty(auth) || !auth.StartsWith("Bearer ", System.StringComparison.OrdinalIgnoreCase))
{
await context.ChallengeAsync();
}
else
{
await next();
}
}
}
else
{
await next();
}
});
然后,javascript应用程序捕获Ajax异常,并检查状态是否为401,并简单地执行 window.location.reload()
这不是一个很好的解决方案,将来可能会重写,但它解决了眼前的问题。