HttpListener与JWT和Basic auth:如何发送WWW-Authenticate? (自托管)

时间:2015-10-22 20:53:50

标签: c# jwt http-basic-authentication httplistener self-hosting

我有一个在mono / .NET上运行跨平台的自托管REST应用程序。一个问题是HttpListener管理和阻止WWW-Authenticate头的手动设置。如果您将自己限制在内置的Basic,NTLM等身份验证中,或者不需要身份验证,那么这很好,但如果您想接受任何其他类型的令牌,则会出现问题。

我使用带有REST样式接口的JWT令牌,使用Basic [1] auth进行初始身份验证。在应用程序的另一部分,我正在做类似的事情,但使用自定义令牌和/或Basic auth作为API的另一部分的后备。

问题:

如何让HttpListener发送" WWW-Authenticate:Basic"挑战标题同时还允许非基本授权令牌通过?

我已经尝试在听众中同时设置Basic和Anonymous:

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

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

如果我只设置AuthenticationSchemes.Basic,HttpListener会拒绝所有没有Basic样式标记的连接,这样做不是很有用。

明显但蹩脚的解决方法:

目前我只是违反HTTP规范并返回401而没有WWW-Authenticate标头。这有效,但会降低与第三方工具的兼容性。

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

想法?

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

1 个答案:

答案 0 :(得分:4)

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

我的项目现在正在使用来自github的MDN OperatorPrecedence table的分支,它是mono-project的HttpListener的分支。这有一个额外的好处,它不使用.NET内置的HTTP支持,所以你的应用程序不需要管理员访问,但缺点(或者是?),你不再有内置但是善良的 - 从框架中获得HTTPS支持的痛苦。 (我建议在任何情况下都使用HTTPS代理(apache或类似)。)

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