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

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`?

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.

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

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

Cheers,
Francis

On 17/05/2017 1:02 AM, Josh Elser wrote:
On Tue, May 16, 2017 at 1:28 AM, F21 <f21.gro...@gmail.com> wrote:
Hey guys,

I recently received a request to add authentication to the Go Avatica
driver.

I am currently investigating ways to implement this. One of the limitations of the Go database/sql package is that all configuration options need to be
passed in through the connection string (DSN). For the Go driver, I
currently have the following:

http://address:port[/schema][?parameter1=value&...parameterN=value]

Parts in between "[" and "]" are optional. Valid parameters are location,
maxRowsTotal, frameMaxSize and transactionIsolation.

Does the Java Avatica thin client support HTTP Basic and Digest
Authentication? After reading the docs on Security[0], I get the impression that it is only useful for gating access to the Avatica server. If using HTTP Basic and Digest auth, is the role required in the client request? If so, what is the HTTP header for sending the role to the server? I am also trying to assess to see if HTTP Basic and Digest authentication is worth
implementing.
It does support Basic and Digest auth, but it's not the most useful in
its current form (IMO). The only authentication "database" it can use
are the flat-files:

e.g. https://wiki.eclipse.org/Jetty/Tutorial/Realms under HashLoginService

We _could_ consider connectors to other authentication systems, but,
being lazy and all, I'd prefer to use some proxy in from of Avatica
that does authentication, authorization, encryption, and
load-balancing for us :)

I think SPNEGO/Kerberos auth is probably the best form of authentication and
is used by Phoenix/HBase and quite a lot of other database backends.
However, the downside is that there is no usable pure-go SPNEGO/Kerberos
library as the only one that exists is still lacking a lot of features.
There is a fork of jmckaskill/gokerb[1] which is more up-to-date but doesn't
look to be actively maintained.

The only option to implement SPNEGO at this point is to use a library that wraps libgssapi, for example apcera/gssapi[2]. However, the downsides of using something like this is that it rely on cgo, which makes it harder to
debug and will make the Go driver unusable on Windows.
Kerberos/SPNEGO is definitely much nicer for organizations to use
(centralized user access via the KDC or Active Directory), but that's
a shame it comes with other caveats from the Go side.

I also noticed that the JDBC driver has support for user and password
parameters which are passed directly to the underlying server. If I want to build support for this, how should the user and password be sent to avatica?
Should I include a `user` and `password` key in the info map within
OpenConnectionRequest[3]?
There are essentially two sets of "users": one for the database and
one for Avatica's authentication. "user" and "password" are passed
directly into the database Avatica is wrapping.

Whereas, the "avatica_user" and "avatica_password" are just extracted
and used for the HTTP authentication with the Avatica server. These
are primarily just something for the Java client to use read
configuration from. The properties are extracted from the JDBC url,
and used by the Java client to set up the HTTP request to the Avatica
server.

You could follow the same approach with the Go driver (or come up with
your own). It's up to you!

Cheers,

Francis


[0]
http://calcite.apache.org/avatica/docs/security.html#http-basic-authentication

[1] https://github.com/jgcallero/gokerb

[2] https://github.com/apcera/gssapi

[3]
http://calcite.apache.org/avatica/docs/protobuf_reference.html#openconnectionrequest



Reply via email to