Hey Josh,

Thanks, that was super useful. I've now implemented HTTP Basic and Digest Auth and passing the JDBC username/password to the backing DB. I want to spin up an Avatica HSQLDB server and have built the docker images. Where should the `jetty-users.properties` file be mounted so that the Avatica server can see it?

Francis

On 20/05/2017 12:53 AM, Josh Elser wrote:


F21 wrote:
Just realized the proposed design does not take into account the
situation where someone wants to do HTTP Basic or Digest auth against
avatica, and then pass a separate username/password pair to the backing db.

On 17/05/2017 9:24 AM, F21 wrote:
Hi Josh,

Thanks for the detailed response!

In terms of the HashLoginService in Jetty, does the client need to
pass a role to Avatica? If so, how is this done?
Also, if I define multiple roles for a given user in Avatica using a
properties file, do they have any actual effect (from what I can see,
Avatica does not seem to use the roles at all)?

No, the user doesn't have a concept of roles. The roles are a Jetty-construct to map a set of users that are logically grouped together. e.g. an "admin" role may be authorized to see resources that a "developers" role may not be authorized.

Here's my summary of the possible authentication methods (let me know
if I miss something):
- HTTP Basic or HTTP Digest authentication against Avatica.
- SPNEGO against Avatica.
- SPNEGO against Avatica that is impersonated, so that the queries
against the database are run against the authenticated user.
- A user and password pair (`user` and `password` keys in the
OpenConnectionRequest map) that is passed straight down to the backing
database (Avatica does not do any authentication).

I am still somewhat confused about using `avatica_user` and
`avatica_password` for HTTP Basic and Digest auth. I am assuming that
instead of passing those as a HTTP header (Authorization: Basic
QWxhZGRpbjpPcGVuU2VzYW1l), I should
set them in the map for OpenConnectionRequest and set the
`authentication` key to either `BASIC` or `DIGEST`?

No: avatica_user and avatica_password are implementation details for the Avatica JDBC driver only. *Each driver* needs to implement hooks for how the HTTP authentication is implemented (if you choose to do so). Specifically, you would need to expose configuration in the Go driver to accept username and password to specifically use for the HTTP requests.

It's certainly a reasonable idea to re-use the same naming as it keeps things concise across client implementations :)

Is passing the user and password pair using `user` and `password`
straight down to the backing database an officially supported method?
That's what was requested with the Go driver. In this instance, they
are using the Phoenix Query Server, but I believe the PQS was modified
to check username/password pairs, as I don't believe Phoenix/HBase
supports username/password auth.

Ok, I think I see where your confusion is coming from.

"user" and "password" are officially supported as they are constructs from JDBC. There is the implicit assumption that these are present (unless your "real backend database" doesn't support them).

Avatica layers more authentication on "top" of that. The big difference is that HTTP Basic/Digest authentication and SPNEGO authentication are done at the "protocol" level. The protocol authentication we're getting isn't directly translated into backend Avatica RPCs.

Implementations of Avatica *can* make an exception to that rule. For example, with Apache Phoenix, we hook into the authenticated user from the SPNEGO request and Avatica "impersonates" the end-user (as we know that the request was strongly authenticated with their Kerberos credentials already). Phoenix/HBase uses that impersonated Kerberos user _in lieu_ of the normal JDBC "user" and "password".

Does this make sense? The core is that we have two separate layers of authentication but you can wire them together in the backend.

For SPNEGO impersonation, is the request automatically impersonated as
long as the backing db has implemented impersonation?

No. In the server-side portion of a SPNEGO handshake, the server *never* sees the client's "keys". It's impossible for Avatica to perform some action as the end user.

How this can work is that Avatica is configured to use its server identity but *say that it is the client*. e.g. "I am <client> here are my credentials: <server_keys>". The reason this can work is if the backend DB is configured to allow the <server> to be treated as <client>. In any other case, this is a security flaw.

In terms of implementation, my current difficulties are:
- Lack of a good pure-go SPNEGO library: Maybe it's possible to
support SPNEGO on *nix-like systems only, while throwing an error if
SPNEGO is used on Windows.

That's a shame. Maybe one will come about if we wait :)

- The need to force all the config into the DSN string (developer
experience). For example, a possible implementation is:

http://username:password@address:port/schema -> pass the username and
password straight through to the backing db

http://username:password@address:port/schema?authentication=BASIC ->
use the username and password for HTTP BASIC auth

http://username:password@address:port/schema?authentication=DIGEST ->
use the username and password for HTTP DIGEST auth

http://address:port/schema?authentication=SPNEGO&principal=some-principal&keytab=/path/to/some/keytab
-> use SPNEGO

In the case of using a username + password, if the authentication
parameter is unintentionally added or omitted, it might not be
apparent why things are not working. I would love to hear what you
guys think about this design.

I'd avoid tying the "wire" authentication to the "database" authentication (as alluded to above). For example, if there is some authentication proxy sitting between client and Avatica server, you may need to provide two different sets of credentials (the wire creds to get through the proxy, and then the real database creds). The former is purely at the HTTP level, the latter would be included in the OpenConnectionRequest.

Hopefully this clarifies some things. Let me know if there is still some confusion. This is admittedly a little weird, but I believe it's (presently) what we want.


Reply via email to