Thank you Diego, this is super helpful!

I just added the headers to the do_handshake response, and now I get past
the authentication issue. I'll follow up with the arrow-rs guys to see if
we can add this change in the repo, it certainly seems to me it would make
sense.

I see another issue, not sure if it is driver related or more on the server
side, but through you might have some ideas. When I try to run a query, the
driver seems to call the server in a loop, roughly these are the service
calls:

arrow.flight.protocol.FlightService/Handshake
arrow.flight.protocol.sql.ActionCreatePreparedStatementRequest

(
arrow.flight.protocol.sql.CreatePreparedStatement
arrow.flight.protocol.sql.CommandPreparedStatementQuery
arrow.flight.protocol.sql.FetchResults
) x5

The driver eventually bombs out with the following error:

java.sql.SQLException: Error while executing SQL "SELECT 1": Failed to
successfully execute query after 5 attempts.
at cfjd.org.apache.calcite.avatica.Helper.createException(Helper.java:56)
at cfjd.org.apache.calcite.avatica.Helper.createException(Helper.java:41)
at
cfjd.org.apache.calcite.avatica.AvaticaStatement.executeQuery(AvaticaStatement.java:235)
at com.fusiongrid.App.main(App.java:29)
at org.codehaus.mojo.exec.ExecJavaMojo.doMain(ExecJavaMojo.java:385)
at org.codehaus.mojo.exec.ExecJavaMojo.doExec(ExecJavaMojo.java:374)
at
org.codehaus.mojo.exec.ExecJavaMojo.lambda$execute$0(ExecJavaMojo.java:296)
at java.base/java.lang.Thread.run(Thread.java:1570)
Caused by: java.lang.RuntimeException: Failed to successfully execute query
after 5 attempts.
at
cfjd.org.apache.calcite.avatica.AvaticaStatement.executeInternal(AvaticaStatement.java:168)
at
cfjd.org.apache.calcite.avatica.AvaticaStatement.executeQuery(AvaticaStatement.java:228)
... 5 more

Have you seen anything like this on other server implementations?



On Thu, Apr 18, 2024 at 11:31 AM Diego Fernandez <aiguo.fernan...@gmail.com>
wrote:

> Interesting... so the Rust AFS server is returning the token in the
> payload? I believe it should be setting it on the returning headers instead.
>
> In the Java server, you decide on the authentication mechanism. The
> equivalent of what you're trying to do is `BearerTokenAuthenticator`, which
> allows you to validate the incoming Basic auth header and set the Bearer
> token header in the response headers.
>
> After a quick look at the JDBC code, it seems like it's looking for the
> header `authorization=Bearer <token>` in the response to set it for
> following requests.
>
> Maybe the Rust server has a similar auth mechanism to
> `BearerTokenAuthenticator`?
>
> On Thu, Apr 18, 2024 at 9:11 AM Istvan Fodor <i...@istvanfodor.com> wrote:
>
>> Hi Jordan,
>> I was testing with the example code in the Apache Arrow Rust repo:
>> https://github.com/apache/arrow-rs/blob/master/arrow-flight/examples/flight_sql_server.rs
>>
>>
>> To the best of my knowledge, it returns a token in the payload. I can see
>> in ngrep that do_handshake is called and this is what it returns:
>>
>> let result = HandshakeResponse {
>>             protocol_version: 0,
>>             payload: FAKE_TOKEN.into(),
>>         };
>> let result = Ok(result);
>> let output = futures::stream::iter(vec![result]);
>> return Ok(Response::new(Box::pin(output)));
>>
>> In the Java code it looks like the authorization header is not part of
>> the metadata that is passed:
>>
>> No authorization header! metadata = MetadataMap { headers:
>> {"content-type": "application/grpc", "te": "trailers", "user-agent":
>> "grpc-java-netty/1.60.0", "username": "admin", "grpc-accept-encoding":
>> "gzip"} }
>>
>> I logged the metadata on the Rust side and the authorization header was
>> missing indeed.
>>
>> IN the Netty logs it looks like the right Basic auth is passed in on
>> getConnection, and the token comes back fine:
>>
>> 10:50:53.890 [grpc-nio-worker-ELG-1-2] DEBUG
>> cfjd.io.grpc.netty.NettyClientHandler -- [id: 0x53dab587, L:/
>> 127.0.0.1:59757 - R:/127.0.0.1:50050] OUTBOUND HEADERS: streamId=3
>> headers=GrpcHttp2OutboundHeaders[:authority: 0.0.0.0:50050, :path:
>> /arrow.flight.protocol.FlightService/Handshake, :method: POST, :scheme:
>> http, content-type: application/grpc, te: trailers, user-agent:
>> grpc-java-netty/1.60.0, username: admin, grpc-accept-encoding: gzip,
>> authorization: Basic YWRtaW46cGFzc3dvcmQ=] streamDependency=0 weight=16
>> exclusive=false padding=0 endStream=false
>> 10:50:53.895 [grpc-nio-worker-ELG-1-2] DEBUG
>> cfjd.io.grpc.netty.NettyClientHandler -- [id: 0x53dab587, L:/
>> 127.0.0.1:59757 - R:/127.0.0.1:50050] OUTBOUND DATA: streamId=3
>> padding=0 endStream=true length=5 bytes=0000000000
>> 10:50:53.898 [grpc-nio-worker-ELG-1-2] DEBUG
>> cfjd.io.grpc.netty.NettyClientHandler -- [id: 0x53dab587, L:/
>> 127.0.0.1:59757 - R:/127.0.0.1:50050] INBOUND HEADERS: streamId=3
>> headers=GrpcHttp2ResponseHeaders[:status: 200, content-type:
>> application/grpc, date: Thu, 18 Apr 2024 15:50:53 GMT] padding=0
>> endStream=false
>> 10:50:53.899 [grpc-nio-worker-ELG-1-2] DEBUG
>> cfjd.io.grpc.netty.NettyClientHandler -- [id: 0x53dab587, L:/
>> 127.0.0.1:59757 - R:/127.0.0.1:50050] INBOUND DATA: streamId=3 padding=0
>> endStream=false length=17 bytes=000000000c120a757569645f746f6b656e
>>
>> Subsequent calls in the JDBC/Netty log don't show the authorization
>> header.
>>
>>
>> On Wed, Apr 17, 2024 at 2:16 PM Istvan Fodor <i...@istvanfodor.com>
>> wrote:
>>
>>> Hi All,
>>>
>>> I am trying to write a basic example of a Java/JDBC code querying from
>>> the Arrow Rust example implementation of the Arrow Flight SQL server (
>>> https://github.com/apache/arrow-rs/blob/master/arrow-flight/examples/flight_sql_server.rs).
>>> My impression was that based on the interoperability goals of the Arrow
>>> project, these should work together just fine.
>>>
>>> It turns out the in my Java code, I can authenticate (getConnection())
>>> fine against the Rust server. User/password goes in, and a token comes
>>> back, but subsequent calls (executeQuery() for example) don't include the
>>> authorization token at all (it should look like authorization=Bearer
>>> <token>), whereas I expected the token to just propagate to subsequent
>>> calls as it should.
>>>
>>> I am using the 15.0.2 flight-sql-jdbc-driver. Any ideas what my issue
>>> could be? Is there any extra setup that we need to do to get JDBC + Basic
>>> auth to work besides supplying user and password parameters?
>>>
>>> Thanks,
>>> Istvan Fodor
>>>
>>

Reply via email to