带有 JWT 和基本身份验证的 HttpListener:如何发送 WWW-Authenticate? (Self-Hosted)

HttpListener with JWT and Basic auth: how to send WWW-Authenticate? (Self-Hosted)

我在 mono/.NET 上有一个 self-hosted REST 应用 运行 跨平台。一个问题是 HttpListener 管理和阻止 WWW-Authenticate header 的手动设置。如果您将自己限制为 built-in 基本、NTLM 等身份验证,或者不需要身份验证,这很好,但如果您想接受任何其他类型的令牌,这就是问题了。

我正在使用具有 REST 风格界面的 JWT 令牌,使用 Basic[1] 身份验证进行初始身份验证。在应用程序的另一部分,我正在做类似的事情,但使用自定义令牌 and/or 基本身份验证作为 API 另一部分的后备。

问题:

如何让 HttpListener 发送 "WWW-Authenticate: Basic" 质询 header 同时允许 non-Basic 授权令牌通过?

我试过在监听器中同时设置基本和匿名:

_listener.AuthenticationSchemes = 
    AuthenticationSchemes.Basic | AuthenticationSchemes.Anonymous;

这导致在任何情况下都不会返回 WWW-Authenticate header。我相信这应该允许基本连接或未经身份验证的连接,并且当我将状态代码设置为 401 (HttpStatusCode.Unauthorized) 时还应该设置 WWW-Authenticate 质询。但它没有(在单声道或 .NET 上)。

如果我只设置 AuthenticationSchemes.Basic,HttpListener 将拒绝所有没有 Basic 样式令牌的连接,这在远程没有用。

明显但蹩脚的解决方法:

目前我只是违反了 HTTP 规范并在没有 WWW-Authenticate header 的情况下返回 401。这可行,但会降低与第三方工具的兼容性。

我考虑过使用完全不同的 HttpListener 实现,尽管大多数似乎都处于原型阶段或属于它们自己的大型库的一部分。我考虑过编写自己的 HttpListener,但此时将整个应用程序移植到 Java 开始看起来很有吸引力。我想找到比完整的平台端口或编写我自己的库更少工作的建议。

想法?

[1] - 此处需要基本身份验证以向后兼容低级脚本和其他一些系统。请假设我了解安全隐患并正在使用 SSL 等。

HttpListener 根本不适用于任何非内置的身份验证。 Microsoft 的实施 非常 积极地将 auth 限制为四种内置类型,仅此而已。对于基于令牌的身份验证或任何其他目的,您不能使用 System.Net.HttpListener.

我的项目现在正在使用tekhedd/SocketHttpListener (on NuGet)(a fork of MediaBrowser/SocketHttpListener,也推荐),它是 mono-project 的 HttpListener 的一个分支。这有一个额外的好处,它不使用 .NET 内置的 HTTP 支持,因此您的应用程序不需要管理员访问权限,但缺点(或者是?)您不再拥有内置但友好的 -框架提供的 HTTPS 支持让您轻松工作。 (我建议在任何情况下都为 HTTPS 使用代理(apache 或类似代理)。)

不确定我是否应该接受我自己的答案,但老实说我还没有找到更好的答案。希望这对某人有所帮助!