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