You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@calcite.apache.org by F21 <f2...@gmail.com> on 2017/05/16 05:28:29 UTC

Avatica and Authentication

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.

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.

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

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


Re: Avatica and Authentication

Posted by Josh Elser <jo...@gmail.com>.
Going off of memory, there is an method you can invoke on the 
HttpServer.Builder class (the builder class invoked to create the 
Avatica server). I think you would call that method with a path to your 
file.

If you're just invoking the StandaloneServer, I think we would just need 
to expose some command-line options to enable authentication and then 
configure it. Right now, you'll have to write some Java code.

On 5/26/17 1:33 AM, F21 wrote:
> 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.
> 
> 

Re: Avatica and Authentication

Posted by F21 <f2...@gmail.com>.
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.



Re: Avatica and Authentication

Posted by Josh Elser <jo...@gmail.com>.

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.

Re: Avatica and Authentication

Posted by F21 <f2...@gmail.com>.
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 <f2...@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 
>>>
>>>
>


Re: Avatica and Authentication

Posted by Josh Elser <jo...@gmail.com>.
On Tue, May 16, 2017 at 1:28 AM, F21 <f2...@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
>