Cleanup Kotlin AuthorizationManagerFactory Generics

This cleans up the generic types within the Kotlin DSL that reference
AuthorizationManagerFactory

Issue gh-17860
This commit is contained in:
Rob Winch 2025-09-23 09:58:19 -05:00
parent 628f3da30b
commit 459b872a20
No known key found for this signature in database
2 changed files with 58 additions and 8 deletions

View File

@ -274,7 +274,7 @@ class AuthorizeHttpRequestsDsl : AbstractRequestMatcherDsl {
}
constructor(context: ApplicationContext) {
this.authorizationManagerFactory = resolveAuthorizationManagerFactory(context)
this.authorizationManagerFactory = resolveAuthorizationManagerFactory(context)
this.authenticated = this.authorizationManagerFactory.authenticated()
this.denyAll = this.authorizationManagerFactory.denyAll()
this.fullyAuthenticated = this.authorizationManagerFactory.fullyAuthenticated()
@ -282,14 +282,14 @@ class AuthorizeHttpRequestsDsl : AbstractRequestMatcherDsl {
}
private fun resolveAuthorizationManagerFactory(context: ApplicationContext): AuthorizationManagerFactory<in RequestAuthorizationContext> {
val specific = context.getBeanProvider<AuthorizationManagerFactory<RequestAuthorizationContext>>().getIfUnique()
if (specific != null) {
return specific
val factoryOfRequestAuthorizationContext = context.getBeanProvider<AuthorizationManagerFactory<RequestAuthorizationContext>>().getIfUnique()
if (factoryOfRequestAuthorizationContext != null) {
return factoryOfRequestAuthorizationContext
}
val type = ResolvableType.forClassWithGenerics(AuthorizationManagerFactory::class.java, Object::class.java)
val general: AuthorizationManagerFactory<in RequestAuthorizationContext>? = context.getBeanProvider<AuthorizationManagerFactory<in RequestAuthorizationContext>>(type).getIfUnique()
if (general != null) {
return general
val factoryOfObjectType = ResolvableType.forClassWithGenerics(AuthorizationManagerFactory::class.java, Object::class.java)
val factoryOfAny = context.getBeanProvider<AuthorizationManagerFactory<Any>>(factoryOfObjectType).getIfUnique()
if (factoryOfAny != null) {
return factoryOfAny
}
val defaultFactory: DefaultAuthorizationManagerFactory<RequestAuthorizationContext> = DefaultAuthorizationManagerFactory()
val rolePrefix = resolveRolePrefix(context)
@ -318,4 +318,5 @@ class AuthorizeHttpRequestsDsl : AbstractRequestMatcherDsl {
}
return NullRoleHierarchy()
}
}

View File

@ -16,10 +16,12 @@
package org.springframework.security.config.annotation.web
import io.mockk.Called
import io.mockk.every
import io.mockk.mockk
import io.mockk.verify
import jakarta.servlet.DispatcherType
import org.aopalliance.intercept.MethodInvocation
import org.assertj.core.api.Assertions.assertThatThrownBy
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
@ -1120,4 +1122,51 @@ class AuthorizeHttpRequestsDslTests {
}
}
}
@Test
fun `custom AuthorizationManagerFactory of MethodInvocation`() {
this.spring.register(AuthorizationManagerFactoryMethodInvocationConfig::class.java).autowire()
val authzManagerFactory =
this.spring.context.getBean<AuthorizationManagerFactory<MethodInvocation>>()
verify(exactly = 0) { authzManagerFactory.authenticated() }
}
@Configuration
@EnableWebSecurity
@EnableWebMvc
open class AuthorizationManagerFactoryMethodInvocationConfig {
val authorizationManager: AuthorizationManager<MethodInvocation> = mockk()
@Bean
open fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
http {
authorizeHttpRequests {
authorize("/authenticated", authenticated)
}
httpBasic { }
rememberMe { }
}
return http.build()
}
@Bean
open fun authorizationManagerFactory(): AuthorizationManagerFactory<MethodInvocation> {
val factory: AuthorizationManagerFactory<MethodInvocation> = mockk()
every { factory.authenticated() } returns this.authorizationManager
return factory
}
@Bean
open fun userDetailsService(): UserDetailsService = InMemoryUserDetailsManager(TestAuthentication.user())
@RestController
internal class OkController {
@GetMapping("/**")
fun ok(): String {
return "ok"
}
}
}
}