缺少 cookie 时,.NET 核心返回 500 而不是 401

标签 .net authentication asp.net-web-api asp.net-core http-status-code-401

我有一个使用 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] 的 Controller 时他们收到 500 状态错误:

InvalidOperationException: No authentication handler is configured to handle the scheme: Automatic

如果我改变 c.AutomaticChallenge = true;然后我得到一个 302 重定向到 {site}/Account/Login?ReturnUrl={api resource it was trying to load} .这很奇怪,因为那不是一条有效的路线而且我没有设置它。

如何解决此问题,以便未经身份验证的用户在服务器上获得 401 而不是 500 异常。

我意识到我可以覆盖它并使用自定义响应编写我自己的身份验证,但必须有一种方法来制作内置的 [Authorize]返回正确的 HTTP 状态代码。

最佳答案

我在使用 Postman 测试端点时遇到了这个问题。

如果您查看 source code对于 OnRedirectToLogin 事件,您可以看到它正在检查请求是否为 AJAX 请求。要使 IsAjaxRequest 返回 trueX-Requested-With header 需要将 XMLHttpRequest 作为其值。

如果您碰巧使用 Postman 对此进行测试,则必须手动应用 X-Requested-With 以及正确的值:

Image for Postman Settings (can't embed images, yet)

最后,如果您没有其他需要设置的特殊配置,您的 CookieAuthenticationOptions 应该是这样的:

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
    AutomaticAuthenticate = true,
    AutomaticChallenge = true
});

关于缺少 cookie 时,.NET 核心返回 500 而不是 401,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43662305/

相关文章:

.net - FluentMigrator.Runner 在输出目录中复制 32 位程序集

authentication - OAuth2 资源所有者密码凭证流程

git - 使用 Windows 身份验证进行私有(private) BitBucket git 存储库?

c# - 通过 Web api 返回图像的问题

c# - 选定区域以剪切图像

c# - 代码优先 : Mapping entities to existing database tables

.net - 无法调试 Windows 服务 - 当前不会命中断点

ruby-on-rails - Rails 设计禁用某些用户类型的密码恢复

jquery - 如何在 Web api MVC 6 中启用跨域请求

c# - 如何将 Stream 转换为对象