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

江枫思渺然 提交于 2019-12-10 19:36:47

问题


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.

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.

The question:

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;

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).

If I only set AuthenticationSchemes.Basic, HttpListener refuses all connections without a Basic style token, which is not remotely useful.

Obvious but lame workaround:

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.

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.

Ideas?

[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.


回答1:


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.

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!



来源:https://stackoverflow.com/questions/33290559/httplistener-with-jwt-and-basic-auth-how-to-send-www-authenticate-self-hosted

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!