HttpContext的ChallengeAsync()不会重定向

时间:2018-12-20 15:37:06

标签: c# asp.net-core identityserver4

我们在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响应,请告诉我要去的地方”?

1 个答案:

答案 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()

这不是一个很好的解决方案,将来可能会重写,但它解决了眼前的问题。