Re: Fwd: HTTP-SASL ...

Hello Christian,

> I'm a GNU maintainer of GNU libmicrohttpd and GNU Taler. Michiel
> (NLnet) repeatedly pointed us to your HTTP-SASL work, and I find it
> quite interesting.

Thanks!  I have been looking into GNU Taler recently, and find it
a pivotal piece of work.  And I would expect that some of the APIs
could benefit from client-chosen authentication strength -- your
RESTful APIs have variations in who may access what payment or
auditing functions.

> 1) What would it take for GNU libmicrohttpd to support SASL-style
> authentication? I honestly don't have a good handle on the
> complexity, but in principle I would be open to a patch adding
> support for SASL to GNU libmicrohttpd. (Compiled-in optionally.)

Lovely.  Doing it optionally makes sense, so it can be used only
in those services that want to use it.  You would either add a
dependency on SASL or, if you feel like using our simple protocol,
relaying SASL traffic to a separately backend process.

Your server would produce 403/407 responses with [Proxy-]Authorization
headers.  The "s2c" token is a base64 representation of a challenge
from SASL, which is treated as binary; the "s2s" token may carry server
state if this is not held in microhttpd (with cryptographic protection).
The client sends a follow-up request with a [WWW-]Authenticate header
cloning the same "s2s" token if any, and a response token from its
client-end SASL in "c2s", which your server needs to map from base64 to
binary.

So there is mostly header parsing/writing, base64/binary conversion
and passing data back and forth to a SASL backend.

As mentioned, we use a protocol to offload SASL traffic to a central
service network node,
https://datatracker.ietf.org/doc/html/draft-vanrein-diameter-sasl#name-centralised-handing-of-sasl
We specifically use this to avoid server-stored accounts; it even
allows us to route login requests back to a SASL identity provider
in the client's own domain.

We made Apache modules for a local Cyrus-SASL2 backend and the
protocol just described,
https://gitlab.com/arpa2/apachemod/-/tree/master/arpa2_sasl
https://gitlab.com/arpa2/apachemod/-/tree/master/arpa2_diasasl

> 2) To use HTTP-SASL for user authentication in GNU Taler/libeufin
> the best way I can see this happen would be via an Nginx or Apache
> reverse proxy setup.

We made both.  The Nginx variant does not use the protocol (yet),
https://github.com/stef/ngx_http_auth_sasl_module
This work was volunteered by Stef, who figured it was easier
to write an HTTP-SASL implementation than to choose various
strategies for various protocols :) which he wanted for his
OPAQUE implementation (modern authentication crypto from IRTF).

> Here, the user would use SASL to authenticate
> against Nginx/Apache using the existing HTTP-SASL enhancements.
> However, next we would (probably?) want to pass some more, eh,
> traditional (HTTP basic/digest/Bearer-token) authentication to the
> libeufin HTTP server (which is Java-based). How easy would that be?

The server decides what it wants to ask, in terms of authentication.
HTTP Authentication requests can enumerate multiple options, though
I'm not sure how well that has been researched.  Most of the times,
I would assume that any concrete URL would want to send at most one
authentication scheme anyway (at the HTTP level) and if that is SASL
it would provide the client a choice (at the SASL-mech level).

I don't think you should have trouble passing along a token with a
successful login response, which your client can then continue to
use.

> Specifically, I'm worried about cases where the URL is not
> user-specific and the account thus MUST be encoded in some
> traditional HTTP authentication style.

We are also pitching a "User:" header to accommodate this kind
of thing.  As long as you are able to send that along with the
request your would be selecting the right account.  (We worked
out caching rules too, avoiding privacy concerns.)

> We can possibly trust the
> reverse proxy and even use the same password (or just bearer token)
> for all accounts, but I think we really at least must be able to
> have the HTTP-SASL logic pass the username through to our HTTP
> server (possibly via some new/custom HTTP header).

This would be the resource's username, right?  That may or may
not coincide with the authenticated username, depending on your
application's ACL.  The proposal introduces a "User:" header in
Section 3.

>  Does your
> existing HTTP-SASL implementation for Nginx/Apache support reverse
> proxy mode and can it pass the username after doing the check?

SASL will basically report "OK" along with the authenticated username
to your proxy (possibly after changing it to a permitted authorisation
identity).

If it now sends an HTTP-SASL response "200 OK" with an "s2s" token,
then clients may repeat that to jump right into further requests.  The
"s2s" token is free-form and could hold the username (in a protected
form) and other session specifics.  Your reverse proxy would detect a
valid "s2s", extract the username and send it to the backend in a
"User:" header.

Lovely examples of the generic ideas, thanks.

> Happy to discuss this further in a telco, via e-mail, or possibly at
> IETF 116 (Yokohama).

Hope to make it to Japan too :)


Cheers,
 -Rick

Received on Saturday, 4 February 2023 20:22:13 UTC