我有一个使用cookie身份验证的.NET核心API . 它由具有自己的登录路径的PWA / SPA访问 .
在 Startup.cs
:
public void ConfigureServices(IServiceCollection services)
{
...
services.AddIdentity<MyUser, MyRole>(options =>
{
...
// Use cookie authentication
var expiresIn = new TimeSpan(1, 0, 0); // 1 hour timeout
var c = options.Cookies.ApplicationCookie;
c.AuthenticationScheme = "appSchemeName";
c.CookieName = "appCookieName";
c.AutomaticAuthenticate = true;
// If this is true auth failures become redirects
c.AutomaticChallenge = false;
c.SlidingExpiration = true;
c.ExpireTimeSpan = expiresIn;
// Store sessions in the cache with the same TTL as the cookie
c.SessionStore = new MyRedisSessionStore(expiresIn);
});
...
}
public void Configure(...)
{
...
app.UseIdentity();
...
app.UseMvc();
}
在我的客户端JS中,当验证cookie无效或丢失时,我期望401,并且在这种情况下显示登录表单 .
但是,当没有有效cookie的用户访问标记为 [Authorize]
的控制器时,他们会收到500状态错误:
InvalidOperationException:没有配置身份验证处理程序来处理该方案:自动
如果我改变 c.AutomaticChallenge = true;
然后我得到302重定向到 {site}/Account/Login?ReturnUrl={api resource it was trying to load}
. 's weird because that'不是有效路线,我没有设置它 .
如何解决此问题,以便未经身份验证的用户在服务器上获得401而不是500例外 .
我意识到我可以覆盖它并使用自定义响应编写自己的身份验证,但必须有一种方法可以使内置的 [Authorize]
返回正确的HTTP状态代码 .
2 回答
当我使用Postman来测试我的 endpoints 时,我遇到了这个问题 .
如果您查看
OnRedirectToLogin
事件的source code,您可以看到它正在检查请求是否是AJAX请求 . 要IsAjaxRequest
返回true
,X-Requested-With
标头需要XMLHttpRequest
作为其值 .如果您碰巧使用Postman进行测试,则必须手动应用X-Requested-With以及正确的值:
最后,如果您没有其他需要设置的特殊配置,这就是您的_1730809应该是什么样子:
我有一个解决方案,因为我有代码可以工作,但它是可怕的,不可能是处理这个问题的最佳方法 .
我当前的代码给出了500服务器错误(当
AutomaticChallenge = false
时)或302重定向(当AutomaticChallenge = true
时) . 两者在我的SPA中都没用,因为500太通用了,而302重定向到一个不存在的页面透明,我在客户端JS得到404 .我的修复是使用302,然后覆盖
Response
:这是有效的,所以它是这个问题的答案,但它是一个可怕的黑客中间件,并没有表现我想要它 .