From 12f0b4ff454bd2f66e49e9d9af5c34ecdc24b47e Mon Sep 17 00:00:00 2001 From: "jan.kozlowski" Date: Thu, 25 Jul 2024 12:28:52 +0200 Subject: [PATCH 1/2] fix jwt impacting lds cache --- .../listeners/filters/JwtFilterFactory.kt | 56 +++++++++++-------- 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/envoy-control-core/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/listeners/filters/JwtFilterFactory.kt b/envoy-control-core/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/listeners/filters/JwtFilterFactory.kt index f91f28e19..d2cd273ce 100644 --- a/envoy-control-core/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/listeners/filters/JwtFilterFactory.kt +++ b/envoy-control-core/src/main/kotlin/pl/allegro/tech/servicemesh/envoycontrol/snapshot/resource/listeners/filters/JwtFilterFactory.kt @@ -25,20 +25,20 @@ class JwtFilterFactory( private val properties: JwtFilterProperties ) { - private val jwtProviderBuilders: Map = getJwtProviderBuilders() + private val jwtProviders: Map = getJwtProviders(failedStatusInMetadataEnabled = false) + private val jwtProvidersWithJwtStatusMetadata: Map = + getJwtProviders(failedStatusInMetadataEnabled = true) private val clientToOAuthProviderName: Map = properties.providers.entries.flatMap { (providerName, provider) -> provider.matchings.keys.map { client -> client to providerName } }.toMap() fun createJwtFilter(group: Group): HttpFilter? { - val configuredJwtProviders = + val selectedJwtProviders = if (group.listenersConfig?.addJwtFailureStatus != false && properties.failedStatusInMetadataEnabled) { - jwtProviderBuilders.mapValues { - it.value.setFailedStatusInMetadata(properties.failedStatusInMetadata).build() - } + jwtProvidersWithJwtStatusMetadata } else { - jwtProviderBuilders.mapValues { it.value.clearFailedStatusInMetadata().build() } + jwtProviders } return if (shouldCreateFilter(group)) { @@ -47,7 +47,7 @@ class JwtFilterFactory( .setTypedConfig( Any.pack( JwtAuthentication.newBuilder().putAllProviders( - configuredJwtProviders + selectedJwtProviders ) .addAllRules(createRules(group.proxySettings.incoming.endpoints)) .build() @@ -68,26 +68,34 @@ class JwtFilterFactory( private fun containsClientsWithSelector(it: IncomingEndpoint) = clientToOAuthProviderName.keys.intersect(it.clients.map { it.name }).isNotEmpty() - private fun getJwtProviderBuilders(): Map = + private fun getJwtProviders(failedStatusInMetadataEnabled: Boolean): Map = properties.providers.entries.associate { - it.key to createProviderBuilder(it.value) + it.key to createProvider(it.value, failedStatusInMetadataEnabled) } - private fun createProviderBuilder(provider: OAuthProvider) = JwtProvider.newBuilder() - .setRemoteJwks( - RemoteJwks.newBuilder().setHttpUri( - HttpUri.newBuilder() - .setUri(provider.jwksUri.toString()) - .setCluster(provider.clusterName) - .setTimeout( - Durations.fromMillis(provider.connectionTimeout.toMillis()) - ).build() + private fun createProvider(provider: OAuthProvider, failedStatusInMetadataEnabled: Boolean): JwtProvider { + val jwtProvider = JwtProvider.newBuilder() + .setRemoteJwks( + RemoteJwks.newBuilder().setHttpUri( + HttpUri.newBuilder() + .setUri(provider.jwksUri.toString()) + .setCluster(provider.clusterName) + .setTimeout( + Durations.fromMillis(provider.connectionTimeout.toMillis()) + ).build() + ) + .setCacheDuration(Durations.fromMillis(provider.cacheDuration.toMillis())) ) - .setCacheDuration(Durations.fromMillis(provider.cacheDuration.toMillis())) - ) - .setForward(properties.forwardJwt) - .setForwardPayloadHeader(properties.forwardPayloadHeader) - .setPayloadInMetadata(properties.payloadInMetadata) + .setForward(properties.forwardJwt) + .setForwardPayloadHeader(properties.forwardPayloadHeader) + .setPayloadInMetadata(properties.payloadInMetadata) + + if (failedStatusInMetadataEnabled) { + jwtProvider.setFailedStatusInMetadata(properties.failedStatusInMetadata) + } + + return jwtProvider.build() + } private fun createRules(endpoints: List): Set { return endpoints.mapNotNull(this::createRuleForEndpoint).toSet() @@ -144,7 +152,7 @@ class JwtFilterFactory( } private val requirementsForProviders: Map = - jwtProviderBuilders.keys.associateWith { JwtRequirement.newBuilder().setProviderName(it).build() } + jwtProviders.keys.associateWith { JwtRequirement.newBuilder().setProviderName(it).build() } private val allowMissingOrFailedRequirement = JwtRequirement.newBuilder().setAllowMissingOrFailed(Empty.getDefaultInstance()).build() From 4c732e0001e7a9d21b36fe13189458ff784b7fd1 Mon Sep 17 00:00:00 2001 From: "jan.kozlowski" Date: Thu, 25 Jul 2024 12:47:10 +0200 Subject: [PATCH 2/2] update CHANGELOG.md --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bb66a081a..a4755f3c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,10 @@ Lists all changes with user impact. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). +## [0.20.17] +### Fixed +- Fix JWT provider configuration to not impact lds cache + ## [0.20.16] ### Changed - Add JWT failure reason to metadata and use it in jwt-status field on denied requests