Use GrantedAuthorityDefaults Bean in Kotlin DSL
Closes gh-15171
This commit is contained in:
parent
24e3bb11bc
commit
a7f9ccb6d6
|
@ -16,6 +16,7 @@
|
|||
|
||||
package org.springframework.security.config.annotation.web
|
||||
|
||||
import org.springframework.context.ApplicationContext
|
||||
import org.springframework.http.HttpMethod
|
||||
import org.springframework.security.authorization.AuthenticatedAuthorizationManager
|
||||
import org.springframework.security.authorization.AuthorityAuthorizationManager
|
||||
|
@ -23,10 +24,11 @@ import org.springframework.security.authorization.AuthorizationDecision
|
|||
import org.springframework.security.authorization.AuthorizationManager
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity
|
||||
import org.springframework.security.config.annotation.web.configurers.AuthorizeHttpRequestsConfigurer
|
||||
import org.springframework.security.config.core.GrantedAuthorityDefaults
|
||||
import org.springframework.security.core.Authentication
|
||||
import org.springframework.security.web.access.IpAddressAuthorizationManager
|
||||
import org.springframework.security.web.access.intercept.AuthorizationFilter
|
||||
import org.springframework.security.web.access.intercept.RequestAuthorizationContext
|
||||
import org.springframework.security.web.access.IpAddressAuthorizationManager
|
||||
import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher
|
||||
import org.springframework.security.web.util.matcher.AnyRequestMatcher
|
||||
import org.springframework.security.web.util.matcher.RequestMatcher
|
||||
|
@ -41,7 +43,7 @@ import java.util.function.Supplier
|
|||
* @since 5.7
|
||||
* @property shouldFilterAllDispatcherTypes whether the [AuthorizationFilter] should filter all dispatcher types
|
||||
*/
|
||||
class AuthorizeHttpRequestsDsl : AbstractRequestMatcherDsl() {
|
||||
class AuthorizeHttpRequestsDsl : AbstractRequestMatcherDsl {
|
||||
@Deprecated("""
|
||||
Add authorization rules to DispatcherType directly.
|
||||
|
||||
|
@ -62,6 +64,7 @@ class AuthorizeHttpRequestsDsl : AbstractRequestMatcherDsl() {
|
|||
var shouldFilterAllDispatcherTypes: Boolean? = null
|
||||
|
||||
private val authorizationRules = mutableListOf<AuthorizationManagerRule>()
|
||||
private val rolePrefix: String
|
||||
|
||||
private val HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME = "mvcHandlerMappingIntrospector"
|
||||
private val HANDLER_MAPPING_INTROSPECTOR = "org.springframework.web.servlet.handler.HandlerMappingIntrospector"
|
||||
|
@ -227,7 +230,7 @@ class AuthorizeHttpRequestsDsl : AbstractRequestMatcherDsl() {
|
|||
* @return the [AuthorizationManager] with the provided role
|
||||
*/
|
||||
fun hasRole(role: String): AuthorizationManager<RequestAuthorizationContext> {
|
||||
return AuthorityAuthorizationManager.hasRole(role)
|
||||
return AuthorityAuthorizationManager.hasAnyRole(this.rolePrefix, arrayOf(role))
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -237,7 +240,7 @@ class AuthorizeHttpRequestsDsl : AbstractRequestMatcherDsl() {
|
|||
* @return the [AuthorizationManager] with the provided roles
|
||||
*/
|
||||
fun hasAnyRole(vararg roles: String): AuthorizationManager<RequestAuthorizationContext> {
|
||||
return AuthorityAuthorizationManager.hasAnyRole(*roles)
|
||||
return AuthorityAuthorizationManager.hasAnyRole(this.rolePrefix, arrayOf(*roles))
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -290,4 +293,18 @@ class AuthorizeHttpRequestsDsl : AbstractRequestMatcherDsl() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
constructor() {
|
||||
this.rolePrefix = "ROLE_"
|
||||
}
|
||||
|
||||
constructor(context: ApplicationContext) {
|
||||
val beanNames = context.getBeanNamesForType(GrantedAuthorityDefaults::class.java)
|
||||
if (beanNames.size > 0) {
|
||||
val grantedAuthorityDefaults = context.getBean(GrantedAuthorityDefaults::class.java);
|
||||
this.rolePrefix = grantedAuthorityDefaults.rolePrefix
|
||||
} else {
|
||||
this.rolePrefix = "ROLE_"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -77,6 +77,7 @@ class HttpSecurityDsl(private val http: HttpSecurity, private val init: HttpSecu
|
|||
private val HANDLER_MAPPING_INTROSPECTOR = "org.springframework.web.servlet.handler.HandlerMappingIntrospector"
|
||||
|
||||
var authenticationManager: AuthenticationManager? = null
|
||||
val context: ApplicationContext = http.getSharedObject(ApplicationContext::class.java)
|
||||
|
||||
/**
|
||||
* Applies a [SecurityConfigurerAdapter] to this [HttpSecurity]
|
||||
|
@ -298,7 +299,7 @@ class HttpSecurityDsl(private val http: HttpSecurity, private val init: HttpSecu
|
|||
* @since 5.7
|
||||
*/
|
||||
fun authorizeHttpRequests(authorizeHttpRequestsConfiguration: AuthorizeHttpRequestsDsl.() -> Unit) {
|
||||
val authorizeHttpRequestsCustomizer = AuthorizeHttpRequestsDsl().apply(authorizeHttpRequestsConfiguration).get()
|
||||
val authorizeHttpRequestsCustomizer = AuthorizeHttpRequestsDsl(this.context).apply(authorizeHttpRequestsConfiguration).get()
|
||||
this.http.authorizeHttpRequests(authorizeHttpRequestsCustomizer)
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,8 @@
|
|||
|
||||
package org.springframework.security.config.annotation.web
|
||||
|
||||
import org.assertj.core.api.Assertions.*
|
||||
import jakarta.servlet.DispatcherType
|
||||
import org.assertj.core.api.Assertions.assertThatThrownBy
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.extension.ExtendWith
|
||||
import org.springframework.beans.factory.UnsatisfiedDependencyException
|
||||
|
@ -28,6 +29,7 @@ import org.springframework.security.authorization.AuthorizationDecision
|
|||
import org.springframework.security.authorization.AuthorizationManager
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
|
||||
import org.springframework.security.config.core.GrantedAuthorityDefaults
|
||||
import org.springframework.security.config.test.SpringTestContext
|
||||
import org.springframework.security.config.test.SpringTestContextExtension
|
||||
import org.springframework.security.core.Authentication
|
||||
|
@ -55,7 +57,6 @@ import org.springframework.web.servlet.config.annotation.PathMatchConfigurer
|
|||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer
|
||||
import org.springframework.web.util.WebUtils
|
||||
import java.util.function.Supplier
|
||||
import jakarta.servlet.DispatcherType
|
||||
|
||||
/**
|
||||
* Tests for [AuthorizeHttpRequestsDsl]
|
||||
|
@ -835,7 +836,6 @@ class AuthorizeHttpRequestsDslTests {
|
|||
@EnableWebSecurity
|
||||
@EnableWebMvc
|
||||
open class HasIpAddressConfig {
|
||||
|
||||
@Bean
|
||||
open fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
|
||||
http {
|
||||
|
@ -853,4 +853,43 @@ class AuthorizeHttpRequestsDslTests {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun `hasRole when prefixed by configured role prefix should fail to configure`() {
|
||||
assertThatThrownBy { this.spring.register(RoleValidationConfig::class.java).autowire() }
|
||||
.isInstanceOf(UnsatisfiedDependencyException::class.java)
|
||||
.hasRootCauseInstanceOf(IllegalArgumentException::class.java)
|
||||
.hasMessageContaining(
|
||||
"ROLE_JUNIPER should not start with ROLE_ since ROLE_ is automatically prepended when using hasAnyRole. Consider using hasAnyAuthority instead."
|
||||
)
|
||||
assertThatThrownBy { this.spring.register(RoleValidationConfig::class.java, GrantedAuthorityDefaultsConfig::class.java).autowire() }
|
||||
.isInstanceOf(UnsatisfiedDependencyException::class.java)
|
||||
.hasRootCauseInstanceOf(IllegalArgumentException::class.java)
|
||||
.hasMessageContaining(
|
||||
"CUSTOM_JUNIPER should not start with CUSTOM_ since CUSTOM_ is automatically prepended when using hasAnyRole. Consider using hasAnyAuthority instead."
|
||||
)
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
@EnableWebMvc
|
||||
open class RoleValidationConfig {
|
||||
@Bean
|
||||
open fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
|
||||
http {
|
||||
authorizeHttpRequests {
|
||||
authorize("/role", hasAnyRole("ROLE_JUNIPER"))
|
||||
authorize("/custom", hasRole("CUSTOM_JUNIPER"))
|
||||
}
|
||||
}
|
||||
return http.build()
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
open class GrantedAuthorityDefaultsConfig {
|
||||
@Bean
|
||||
open fun grantedAuthorityDefaults(): GrantedAuthorityDefaults {
|
||||
return GrantedAuthorityDefaults("CUSTOM_")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue