-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Set Authorization header dynamically #347
Comments
Thank you for your feedback. It makes sense, I'm currently pondering whether this could be an addition upstream or it should instead be added to this agent. In either case, it's definitely a feature that will get added soon. In the meantime, a workaround could be providing your own custom exporters via |
Thanks! I did exactly this as a tmp solution and can confirm it works. Though a more flexible out-of-the-box headers solution would be way better than this class DynamicHeadersSignalConfiguration(
private val connectivity: ConnectivityConfiguration
) : DefaultSignalProcessorConfiguration() {
override fun provideSpanExporter(): SpanExporter {
return when (connectivity.exportProtocol) {
ExportProtocol.GRPC -> otlpGrpcSpanExporter
ExportProtocol.HTTP -> otlpHttpSpanExporter
else -> throw IllegalArgumentException()
}
}
override fun provideLogExporter(): LogRecordExporter {
return when (connectivity.exportProtocol) {
ExportProtocol.GRPC -> otlpGrpcLogRecordExporter
ExportProtocol.HTTP -> otlpHttpLogRecordExporter
else -> throw IllegalArgumentException()
}
}
override fun provideMetricExporter(): MetricExporter {
return when (connectivity.exportProtocol) {
ExportProtocol.GRPC -> otlpGrpcMetricExporter
ExportProtocol.HTTP -> otlpHttpMetricExporter
else -> throw IllegalArgumentException()
}
}
private val otlpGrpcSpanExporter: OtlpGrpcSpanExporter
get() {
val exporterBuilder =
OtlpGrpcSpanExporter.builder()
.setEndpoint(connectivity.endpoint)
.setHeaders {
buildMap {
putAuthHeader()
}
}
return exporterBuilder.build()
}
private val otlpGrpcLogRecordExporter: OtlpGrpcLogRecordExporter
get() {
val exporterBuilder =
OtlpGrpcLogRecordExporter.builder()
.setEndpoint(connectivity.endpoint)
.setHeaders {
buildMap {
putAuthHeader()
}
}
return exporterBuilder.build()
}
private val otlpGrpcMetricExporter: OtlpGrpcMetricExporter
get() {
val exporterBuilder = OtlpGrpcMetricExporter.builder()
.setAggregationTemporalitySelector(AggregationTemporalitySelector.deltaPreferred())
.setEndpoint(connectivity.endpoint)
.setHeaders {
buildMap {
connectivity.authConfiguration.asAuthorizationHeaderValue()?.takeIf { it.isNotEmpty() }?.also {
put(AUTHORIZATION_HEADER_NAME, it)
}
}
}
return exporterBuilder.build()
}
private val otlpHttpSpanExporter: OtlpHttpSpanExporter
get() {
val exporterBuilder =
OtlpHttpSpanExporter.builder()
.setEndpoint(getHttpEndpoint("traces"))
.setHeaders {
buildMap {
putAuthHeader()
}
}
return exporterBuilder.build()
}
private val otlpHttpLogRecordExporter: OtlpHttpLogRecordExporter
get() {
val exporterBuilder =
OtlpHttpLogRecordExporter.builder()
.setEndpoint(getHttpEndpoint("logs"))
.setHeaders {
buildMap {
putAuthHeader()
}
}
return exporterBuilder.build()
}
private val otlpHttpMetricExporter: OtlpHttpMetricExporter
get() {
val exporterBuilder = OtlpHttpMetricExporter.builder()
.setAggregationTemporalitySelector(AggregationTemporalitySelector.deltaPreferred())
.setEndpoint(getHttpEndpoint("metrics"))
.setHeaders {
buildMap {
putAuthHeader()
}
}
return exporterBuilder.build()
}
private fun getHttpEndpoint(signalId: String): String {
return String.format("%s/v1/%s", connectivity.endpoint, signalId)
}
private fun MutableMap<String, String>.putAuthHeader() {
connectivity.authConfiguration?.asAuthorizationHeaderValue()?.takeIf { it.isNotEmpty() }?.also {
put(AUTHORIZATION_HEADER_NAME, it)
}
}
companion object {
private const val AUTHORIZATION_HEADER_NAME = "Authorization"
}
} |
Glad to know it worked. I'm currently proposing this change upstream, I'll come back here once there's a response from the community. If they deny it I'll add the option to the Elastic agent only. |
In this context, it would be also great to have a stop, flush & cleanup functionality: e.g. if it's critical to cleanup any session related data once user logs out. Currently, there is |
Context
Connectivity
is used to provide custom authorization header value. It's used once the whole apm agent is being initialized.Issue
The whole APM service could live behind a custom auth proxy server, and authorization token could change dynamically. Currently there is no way to change the auth token value without resetting and re-initializing the whole agent.
Possible solution
Let
Connectivity
return "provider" forauthConfiguration()
and usesetHeaders(Supplier<Map<String, String>> headerSupplier)
instead ofaddHeader(...)
for exporters.Even better would be to clone
setHeader
behaviour forConnectivity
to return a set of headers for every request instead of single auth header value -> because e.g. proxy server could demand some custom headers to identify user – this would be the most flexible yet easy implementable for current key/secret predefined variants.The text was updated successfully, but these errors were encountered: