Hi,
Is there a way of preventing a security context from being called twice?
I have an API Gateway, with a Token Relay filter. The security context gets called there, by the TokenRelayGatewayFilterFactory (a custom one or the default), for say an endpoint:
/api/resource/projects
// routing for Resource Server
.route("resource-server") { r ->
r.path("/api${serverProperties.resourceServerPrefix}/**")
.filters { f ->
f.filter { exchange, chain ->
println("Running token relay for: ${exchange.request.uri.path}")
chain.filter(exchange)
}
f.filter(customTokenRelayGatewayFilterFactory.apply(AbstractGatewayFilterFactory.NameConfig()))
.removeRequestHeader("Cookie")
.dedupeResponseHeader("Access-Control-Allow-Credentials", "RETAIN_UNIQUE")
.dedupeResponseHeader("Access-Control-Allow-Origin", "RETAIN_UNIQUE")
}
.uri(serverProperties.resourceServerUri)
}
BUT, the security context is called again in my server logs, and I can only speculate that it is because of the main security chain configuration here.
// security context
http.securityContextRepository(redisSecurityContextRepository)
It seems sub-optimum to have to hit the Security Context Store, e.g. Redis, twice, for every point request?
Describe the bug A clear and concise description of what the bug is.
To Reproduce Steps to reproduce the behavior.
Expected behavior A clear and concise description of what you expected to happen.
Sample
A link to a GitHub repository with a minimal, reproducible sample.
Reports that include a sample will take priority over reports that do not. At times, we may require a sample, so it is good to try and include a sample up front.
Comment From: dreamstar-enterprises
Here is what I see. The 2nd call is what is called by Token Relay, and what triggers the Authorized Client call too. The 1st call, I'm quite sure is due to the main security chain.
.. Also, doing this, didn't help much either. The security context was still called, by I believe the main security filter, even for these end points.
// Define base paths and file extensions for static resources
private val staticResourceMap = mapOf(
"/api/resource/" to listOf("jpg", "png", "gif", "css", "js", "map"),
)
// Define base paths and file extensions for security context loading
private val skipSecurityContextLoading = mapOf(
"/api/resource/" to listOf("jpg", "png", "gif", "css", "js", "map"),
"/login-options" to listOf()
)
@Bean
fun webSecurityCustomizer(): WebSecurityCustomizer {
// Generate patterns for static resources
val staticPatterns = staticResourceMap.flatMap { (basePath, extensions) ->
if (extensions.isEmpty()) {
listOf(basePath)
} else {
getStaticResourcePatterns(basePath, extensions)
}
}.toTypedArray()
// Print the ignored paths
println("Ignoring the following static resource paths:")
staticPatterns.forEach { pattern ->
println(pattern)
}
// Does not (for some reason!) prevent security context from still being loaded!
return WebSecurityCustomizer { web: WebSecurity ->
web.debug(false)
.ignoring()
.requestMatchers(
"/favicon.ico",
*staticPatterns
)
}
}
private fun getStaticResourcePatterns(basePath: String, extensions: List<String>): List<String> {
return extensions.map { "$basePath**/*.$it" }
}
Comment From: dreamstar-enterprises
I think I was able to fix this: https://github.com/dreamstar-enterprises/docs/blob/master/Spring%20BFF/bff/auth/repositories/securitycontext/RedisSecurityContextRepository.kt
I didn't realise a Mono itself, on a particular request had it's own internal request cache.
This stoped the repo call from being made twice.
The below DID NOT work though... (stop the security context from being called)
`
@Bean
fun webSecurityCustomizer(): WebSecurityCustomizer {
// Generate patterns for static resources
val staticPatterns = staticResourceMap.flatMap { (basePath, extensions) ->
if (extensions.isEmpty()) {
listOf(basePath)
} else {
getStaticResourcePatterns(basePath, extensions)
}
}.toTypedArray()
// Print the ignored paths
println("Ignoring the following static resource paths:")
staticPatterns.forEach { pattern ->
println(pattern)
}
// Does not (for some reason!) prevent security context from still being loaded!
return WebSecurityCustomizer { web: WebSecurity ->
web.debug(false)
.ignoring()
.requestMatchers(
"/favicon.ico",
*staticPatterns
)
}
}`
So I had to implement a filter and place that in the security chain instead
And then place this filter in my main security chain:
https://github.com/dreamstar-enterprises/docs/blob/master/Spring%20BFF/bff/auth/BffSecurityConfig.kt
Lots of learning...
Comment From: dreamstar-enterprises
The call is now only made once: