简体   繁体   English

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

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

I have a self-hosted REST app running cross platform on mono/.NET. 我有一个在mono / .NET上运行跨平台的自托管REST应用程序。 The one problem is that HttpListener manages and blocks manual setting of the WWW-Authenticate header. 一个问题是HttpListener管理和阻止WWW-Authenticate头的手动设置。 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. 如果您将自己限制为内置的Basic,NTLM等身份验证,或者不需要身份验证,那么这很好,但如果您想接受任何其他类型的令牌,则会出现问题。

I am using JWT tokens with a REST style interface, using Basic[1] auth for the initial authentication. 我使用带有REST样式接口的JWT令牌,使用Basic [1] auth进行初始身份验证。 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. 在应用程序的另一部分,我正在做类似的事情,但使用自定义令牌和/或Basic auth作为API的另一部分的后备。

The question: 问题:

How can I get HttpListener to send the "WWW-Authenticate: Basic" challenge header while also allowing non-Basic Authorization tokens through? 如何让HttpListener发送“WWW-Authenticate:Basic”质询标题,同时还允许非基本授权令牌通过?

I have tried setting both Basic and Anonymous in the listener thusly: 我已经尝试在侦听器中同时设置Basic和Anonymous:

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

This results in no WWW-Authenticate header being returned under any circumstances. 这导致在任何情况下都不返回WWW-Authenticate标头。 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). 我相信这应该允许基本或未经身份验证的连接,并且当我将状态代码设置为401(HttpStatusCode.Unauthorized)时,还应该设置WWW-Authenticate挑战。 But it does not (on either mono or .NET). 但它没有(在单声道或.NET上)。

If I only set AuthenticationSchemes.Basic, HttpListener refuses all connections without a Basic style token, which is not remotely useful. 如果我只设置AuthenticationSchemes.Basic,HttpListener将拒绝所有没有Basic样式标记的连接,这对于远程用途并不重要。

Obvious but lame workaround: 明显但蹩脚的解决方法:

Currently I am simply violating the HTTP specification and returning 401 without a WWW-Authenticate header. 目前我只是违反HTTP规范并返回401而没有WWW-Authenticate标头。 This works, but reduces compatibility with third party tools. 这有效,但会降低与第三方工具的兼容性。

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. 我考虑使用完全不同的HttpListener实现,尽管大多数似乎是在原型阶段或自己的大型库的一部分。 I have considered writing my own HttpListener, but at that point porting the entire application to Java begins to look attractive. 我考虑过编写自己的HttpListener,但在那时将整个应用程序移植到Java开始看起来很有吸引力。 I would like to find recommendations that are less work than a complete platform port or writing my own library. 我想找到比完整的平台端口或编写自己的库更少工作的建议。

Ideas? 想法?

[1] - Basic auth is needed here for backward compatibility with low level scripts and some other systems. [1] - 此处需要基本身份验证,以便与低级脚本和其他一些系统向后兼容。 Please assume that I understand the security implications and am using SSL, etc. 请假设我了解安全隐患并使用SSL等。

HttpListener simply won't work for any auth that is not built-in. HttpListener根本不适用于任何非内置的auth。 Microsoft's implementation is very aggressive about restricting auth to the four built-in types, and that's that. 微软的实施非常积极地将auth限制为四种内置类型,就是这样。 For token based auth or any other purpose, you can't use System.Net.HttpListener. 对于基于令牌的身份验证或任何其他目的,您不能使用System.Net.HttpListener。

My project is now using (a fork of) MediaBrowser/SocketHttpListener from github, which is a fork of mono-project's HttpListener. 我的项目现在使用来自github的(一个分支) MediaBrowser / SocketHttpListener ,它是mono-project的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. 这有一个额外的好处,它不使用.NET内置的HTTP支持,所以你的应用程序不需要管理员访问权限,但缺点(或者是吗?)你不再拥有内置但是善良的 - 从框架中获得HTTPS支持的痛苦。 (I recommend using a proxy (apache or similar) for HTTPS in any case.) (我建议在任何情况下都使用HTTPS代理(apache或类似)。)

Not sure whether I should accept my own answer here, but I honestly haven't found a better answer. 不确定我是否应该接受我自己的答案,但老实说,我没有找到更好的答案。 Hope this helps somebody! 希望这有助于某人!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM