-
Notifications
You must be signed in to change notification settings - Fork 4k
Description
Describe the usage question you have. Please include as many useful details as possible.
We're currently building a Flight SQL Server and want to use CallHeaderAuthenticator. We want to use token based auth, but the user needs to provide some extra fields (accountId and environmentId). We need to validate the token, and then ensure the user is authorized for the provided accountId and environmentId.
When I pass custom properties to the JDBC URL, they appear in the headers server-side on some requests, but not all.
Here's what we have (CallHeadersWrapper simply creates an object with our custom headers out of passed in headers or a call context).
class CustomBearerTokenAuthenticator(
private val authClient: AuthClient,
private val logger: Logger
) :
CallHeaderAuthenticator {
private val authException = CallStatus.UNAUTHENTICATED.withDescription("Invalid credentials")
override fun authenticate(incomingHeaders: CallHeaders?): CallHeaderAuthenticator.AuthResult {
val bearerToken = AuthUtilities.getValueFromAuthHeader(incomingHeaders, Auth2Constants.BEARER_PREFIX)
?: throw authException.toRuntimeException()
logger.info("Calling auth with headers: ${incomingHeaders.toString()}")
val customHeaders: CallHeadersWrapper =
incomingHeaders?.let { CallHeadersWrapper(it, logger) } ?: throw authException.toRuntimeException()
// if (customHeaders.accountId == null) {
// throw authException.withDescription("Parameter accountId is required").toRuntimeException()
// }
// if (customHeaders.environmentId == null) {
// throw authException.withDescription("Parameter environmentId is required").toRuntimeException()
// }
// FIXME: looks like we don't have access to our custom headers during initial auth... some requests include our custom headers and some don't
if (authClient.isValid(
bearerToken,
customHeaders.accountId ?: "1",
customHeaders.environmentId ?: "12"
)
) {
return createAuthResult(bearerToken)
} else {
logger.info("Bearer token validation failed.")
throw authException.toRuntimeException()
}
}
private fun createAuthResult(token: String): CallHeaderAuthenticator.AuthResult {
class AuthResult : CallHeaderAuthenticator.AuthResult {
override fun appendToOutgoingHeaders(outgoingHeaders: CallHeaders?) {
// TODO: we could store other info in headers to track session
outgoingHeaders?.insert(
"authenticated", "yes"
)
}
override fun getPeerIdentity(): String {
// TODO: peer identity is an identifier for the actor, maybe we want to
// include other things like accountId and projectId
return "person"
}
}
return AuthResult()
}
}
When we use this JDBC connection string: jdbc:arrow-flight-sql://localhost:8811;useEncryption=false;accountId=1;envId=42;token=123 this is the output server side when I establish a connection to the server using DBeaver or DataGrip:
18:29:04.156 [flight-server-default-executor-3] INFO logger -- Calling auth with headers: Metadata(content-type=application/grpc,user-agent=grpc-java-netty/1.49.1,grpc-accept-encoding=gzip,authorization=Bearer 123)
18:29:04.161 [flight-server-default-executor-1] INFO logger -- Calling auth with headers: Metadata(content-type=application/grpc,user-agent=grpc-java-netty/1.49.1,envid=42,accountid=1,grpc-accept-encoding=gzip,authorization=Bearer 123)
18:29:04.165 [flight-server-default-executor-1] INFO logger -- Calling auth with headers: Metadata(content-type=application/grpc,user-agent=grpc-java-netty/1.49.1,grpc-accept-encoding=gzip,authorization=Bearer 123)
18:29:04.170 [flight-server-default-executor-1] INFO logger -- Calling auth with headers: Metadata(content-type=application/grpc,user-agent=grpc-java-netty/1.49.1,envid=42,accountid=1,grpc-accept-encoding=gzip,authorization=Bearer 123)
18:29:04.173 [flight-server-default-executor-1] INFO logger -- Calling auth with headers: Metadata(content-type=application/grpc,user-agent=grpc-java-netty/1.49.1,grpc-accept-encoding=gzip,authorization=Bearer 123)
18:29:04.178 [flight-server-default-executor-1] INFO logger -- Calling auth with headers: Metadata(content-type=application/grpc,user-agent=grpc-java-netty/1.49.1,envid=42,accountid=1,grpc-accept-encoding=gzip,authorization=Bearer 123)
18:29:04.180 [flight-server-default-executor-1] INFO logger -- Calling auth with headers: Metadata(content-type=application/grpc,user-agent=grpc-java-netty/1.49.1,grpc-accept-encoding=gzip,authorization=Bearer 123)
18:29:04.183 [flight-server-default-executor-1] INFO logger -- Calling auth with headers: Metadata(content-type=application/grpc,user-agent=grpc-java-netty/1.49.1,envid=42,accountid=1,grpc-accept-encoding=gzip,authorization=Bearer 123)
Am I misunderstanding something about how the headers are supposed to work here? any help would be greatly appreciated!
Component(s)
Java