2015-10-22 44 views
3

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

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

问题:

我怎样才能得到HttpListener发送“WWW身份验证:基本”,同时还允许非基本授权令牌通过挑战头?

我试图同时设置在听众正是如此基本和匿名:

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

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

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

明显,但跛脚的解决方法:

目前我只是违反了HTTP规范,并没有一个WWW-Authenticate头回401。这会起作用,但会降低与第三方工具的兼容性。

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

想法?

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

回答

4

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

我的项目现在使用来自github的MediaBrowser/SocketHttpListener(一个分支),它是单项目的HttpListener的一个分支。这还有一个好处,就是它不使用.NET内置的HTTP支持,所以你的应用程序不需要管理员访问,但是缺点(或者说它是什么?)你不再拥有内置的 - 但是 - 通过框架中的HTTPS支持来减轻工作负担。 (我建议在任何情况下都使用代理(Apache或类似的)用于HTTPS。)

不确定我是否应该接受我自己的答案,但我确实没有找到更好的答案。希望这可以帮助别人!