问题描述
我有一个在Mono/.NET上跨平台运行的自托管REST应用程序.一个问题是HttpListener管理和阻止WWW-Authenticate标头的手动设置.如果您将自己限制在内置的Basic,NTLM等身份验证中,或者不需要身份验证,那很好,但是如果您要接受任何其他类型的令牌,这是一个问题.
I have a self-hosted REST app running cross platform on mono/.NET. The one problem is that HttpListener manages and blocks manual setting of the WWW-Authenticate header. Which is fine if you limit yourself to the built-in Basic, NTLM, etc authentication, or don't need authentication, but is a problem if you want to accept any other kind of tokens.
我正在将JWT令牌与REST样式接口一起使用,并使用Basic [1] auth进行初始身份验证.在应用程序的另一部分中,我正在执行类似的操作,但在API的另一部分中使用自定义令牌和/或基本身份验证作为后备.
I am using JWT tokens with a REST style interface, using Basic[1] auth for the initial authentication. In another part of the app, I am doing something similar but using custom tokens and/or Basic auth as a fallback in another part of the API.
问题:
如何让HttpListener发送"WWW-Authenticate:Basic"质询标头,同时还允许非基本授权令牌通过?
How can I get HttpListener to send the "WWW-Authenticate: Basic" challenge header while also allowing non-Basic Authorization tokens through?
因此,我尝试在侦听器中同时设置基本"和匿名":
I have tried setting both Basic and Anonymous in the listener thusly:
_listener.AuthenticationSchemes =
AuthenticationSchemes.Basic | AuthenticationSchemes.Anonymous;
在任何情况下都不会返回WWW-Authenticate标头.我认为这应该允许基本或未经身份验证的连接,并且当我将状态代码设置为401(HttpStatusCode.Unauthorized)时,还应该设置WWW-Authenticate质询.但这不是(在mono或.NET上).
This results in no WWW-Authenticate header being returned under any circumstances. I believe this is supposed to allow either Basic or unauthenticated connections, and should also set the WWW-Authenticate challenge when I set the status code to 401 (HttpStatusCode.Unauthorized). But it does not (on either mono or .NET).
如果仅设置AuthenticationSchemes.Basic,则HttpListener会拒绝没有基本样式令牌的所有连接,而这并不是远程使用的.
If I only set AuthenticationSchemes.Basic, HttpListener refuses all connections without a Basic style token, which is not remotely useful.
显而易见的解决方法:
当前,我只是违反了HTTP规范,并返回了没有WWW-Authenticate标头的401.这行得通,但是降低了与第三方工具的兼容性.
Currently I am simply violating the HTTP specification and returning 401 without a WWW-Authenticate header. This works, but reduces compatibility with third party tools.
我考虑使用一种完全不同的HttpListener实现,尽管大多数似乎都处于原型阶段或属于自己的大型库的一部分.我已经考虑过编写自己的HttpListener,但是从那时起,将整个应用程序移植到Java看起来就很有吸引力.我想找到比完整的平台端口或编写我自己的库要少的建议.
I have considered using a completely different HttpListener implementation, although most seem to be either in the prototype stage or part of a large library of their own. I have considered writing my own HttpListener, but at that point porting the entire application to Java begins to look attractive. I would like to find recommendations that are less work than a complete platform port or writing my own library.
想法?
[1]-此处需要基本身份验证,以便与低级脚本和某些其他系统向后兼容.请假设我了解安全隐患,并且正在使用SSL等.
[1] - Basic auth is needed here for backward compatibility with low level scripts and some other systems. Please assume that I understand the security implications and am using SSL, etc.
推荐答案
HttpListener根本不适用于任何非内置身份验证.微软的实施非常积极地将auth限制为四种内置类型,仅此而已.出于基于令牌的身份验证或任何其他目的,您不能使用System.Net.HttpListener.
HttpListener simply won't work for any auth that is not built-in. Microsoft's implementation is very aggressive about restricting auth to the four built-in types, and that's that. For token based auth or any other purpose, you can't use System.Net.HttpListener.
我的项目现在正在使用github上的 MediaBrowser/SocketHttpListener (的一个分支)单个项目的HttpListener的分支.这样做还有一个好处,就是它不使用.NET内置的HTTP支持,因此您的应用程序不需要管理员访问权限,但是缺点是(或者是?)您不再拥有内置的,但种类丰富的-框架的HTTPS支持使工作变得痛苦. (无论如何,我建议在HTTPS中使用代理(apache或类似的代理).)
My project is now using (a fork of) MediaBrowser/SocketHttpListener from github, which is a fork of mono-project's HttpListener. This has the added benefit that it does not use the .NET built-in HTTP support, so your app does not require admin access, but the disadvantage (or is it?) that you no longer have built-in-but-kind-of-a-pain-to-work-with HTTPS support from the framework. (I recommend using a proxy (apache or similar) for HTTPS in any case.)
不确定我是否应该在这里接受自己的答案,但是老实说,我还没有找到更好的答案.希望这对某人有帮助!
Not sure whether I should accept my own answer here, but I honestly haven't found a better answer. Hope this helps somebody!
这篇关于具有JWT和基本身份验证的HttpListener:如何发送WWW-Authenticate? (自托管)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!