Bladeren bron

Add shouldFilterAllDispatcherTypes to Kotlin DSL

Closes gh-11153
Marcus Da Coregio 3 jaren geleden
bovenliggende
commit
a0232ed135

+ 7 - 0
config/src/main/kotlin/org/springframework/security/config/annotation/web/AuthorizeHttpRequestsDsl.kt

@@ -24,6 +24,7 @@ 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.core.Authentication
+import org.springframework.security.web.access.intercept.AuthorizationFilter
 import org.springframework.security.web.access.intercept.RequestAuthorizationContext
 import org.springframework.security.web.util.matcher.AnyRequestMatcher
 import org.springframework.security.web.util.matcher.RequestMatcher
@@ -35,8 +36,11 @@ import java.util.function.Supplier
  *
  * @author Yuriy Savchenko
  * @since 5.7
+ * @property shouldFilterAllDispatcherTypes whether the [AuthorizationFilter] should filter all dispatcher types
  */
 class AuthorizeHttpRequestsDsl : AbstractRequestMatcherDsl() {
+    var shouldFilterAllDispatcherTypes: Boolean? = null
+
     private val authorizationRules = mutableListOf<AuthorizationManagerRule>()
 
     private val HANDLER_MAPPING_INTROSPECTOR = "org.springframework.web.servlet.handler.HandlerMappingIntrospector"
@@ -248,6 +252,9 @@ class AuthorizeHttpRequestsDsl : AbstractRequestMatcherDsl() {
                     }
                 }
             }
+            shouldFilterAllDispatcherTypes?.also { shouldFilter ->
+                requests.shouldFilterAllDispatcherTypes(shouldFilter)
+            }
         }
     }
 }

+ 153 - 0
config/src/test/kotlin/org/springframework/security/config/annotation/web/AuthorizeHttpRequestsDslTests.kt

@@ -53,7 +53,9 @@ import org.springframework.web.bind.annotation.RestController
 import org.springframework.web.servlet.config.annotation.EnableWebMvc
 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]
@@ -641,4 +643,155 @@ class AuthorizeHttpRequestsDslTests {
             return http.build()
         }
     }
+
+    @Test
+    fun `request when shouldFilterAllDispatcherTypes and denyAll and ERROR then responds with forbidden`() {
+        this.spring.register(ShouldFilterAllDispatcherTypesTrueDenyAllConfig::class.java).autowire()
+
+        this.mockMvc.perform(get("/path")
+            .with { request ->
+                request.setAttribute(WebUtils.ERROR_REQUEST_URI_ATTRIBUTE, "/error")
+                request.apply {
+                    dispatcherType = DispatcherType.ERROR
+                }
+            })
+            .andExpect(status().isForbidden)
+    }
+
+    @EnableWebSecurity
+    @EnableWebMvc
+    open class ShouldFilterAllDispatcherTypesTrueDenyAllConfig {
+
+        @Bean
+        open fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
+            http {
+                authorizeHttpRequests {
+                    shouldFilterAllDispatcherTypes = true
+                    authorize(anyRequest, denyAll)
+                }
+            }
+            return http.build()
+        }
+
+        @RestController
+        internal class PathController {
+            @RequestMapping("/path")
+            fun path() {
+            }
+        }
+
+    }
+
+    @Test
+    fun `request when shouldFilterAllDispatcherTypes and permitAll and ERROR then responds with ok`() {
+        this.spring.register(ShouldFilterAllDispatcherTypesTruePermitAllConfig::class.java).autowire()
+
+        this.mockMvc.perform(get("/path")
+            .with { request ->
+                request.setAttribute(WebUtils.ERROR_REQUEST_URI_ATTRIBUTE, "/error")
+                request.apply {
+                    dispatcherType = DispatcherType.ERROR
+                }
+            })
+            .andExpect(status().isOk)
+    }
+
+    @EnableWebSecurity
+    @EnableWebMvc
+    open class ShouldFilterAllDispatcherTypesTruePermitAllConfig {
+
+        @Bean
+        open fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
+            http {
+                authorizeHttpRequests {
+                    shouldFilterAllDispatcherTypes = true
+                    authorize(anyRequest, permitAll)
+                }
+            }
+            return http.build()
+        }
+
+        @RestController
+        internal class PathController {
+            @RequestMapping("/path")
+            fun path() {
+            }
+        }
+
+    }
+
+    @Test
+    fun `request when shouldFilterAllDispatcherTypes false and ERROR dispatcher then responds with ok`() {
+        this.spring.register(ShouldFilterAllDispatcherTypesFalseAndDenyAllConfig::class.java).autowire()
+
+        this.mockMvc.perform(get("/path")
+            .with { request ->
+                request.setAttribute(WebUtils.ERROR_REQUEST_URI_ATTRIBUTE, "/error")
+                request.apply {
+                    dispatcherType = DispatcherType.ERROR
+                }
+            })
+            .andExpect(status().isOk)
+    }
+
+    @EnableWebSecurity
+    @EnableWebMvc
+    open class ShouldFilterAllDispatcherTypesFalseAndDenyAllConfig {
+
+        @Bean
+        open fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
+            http {
+                authorizeHttpRequests {
+                    shouldFilterAllDispatcherTypes = false
+                    authorize(anyRequest, denyAll)
+                }
+            }
+            return http.build()
+        }
+
+        @RestController
+        internal class PathController {
+            @RequestMapping("/path")
+            fun path() {
+            }
+        }
+
+    }
+
+    @Test
+    fun `request when shouldFilterAllDispatcherTypes omitted and ERROR dispatcher then responds with forbidden`() {
+        this.spring.register(ShouldFilterAllDispatcherTypesOmittedAndDenyAllConfig::class.java).autowire()
+
+        this.mockMvc.perform(get("/path")
+            .with { request ->
+                request.setAttribute(WebUtils.ERROR_REQUEST_URI_ATTRIBUTE, "/error")
+                request.apply {
+                    dispatcherType = DispatcherType.ERROR
+                }
+            })
+            .andExpect(status().isForbidden)
+    }
+
+    @EnableWebSecurity
+    @EnableWebMvc
+    open class ShouldFilterAllDispatcherTypesOmittedAndDenyAllConfig {
+
+        @Bean
+        open fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
+            http {
+                authorizeHttpRequests {
+                    authorize(anyRequest, denyAll)
+                }
+            }
+            return http.build()
+        }
+
+        @RestController
+        internal class PathController {
+            @RequestMapping("/path")
+            fun path() {
+            }
+        }
+
+    }
 }

+ 14 - 0
docs/modules/ROOT/pages/servlet/authorization/authorize-http-requests.adoc

@@ -190,4 +190,18 @@ SecurityFilterChain web(HttpSecurity http) throws Exception {
     return http.build();
 }
 ----
+.Kotlin
+[source,kotlin,role="secondary"]
+----
+@Bean
+open fun web(http: HttpSecurity): SecurityFilterChain {
+    http {
+        authorizeHttpRequests {
+            shouldFilterAllDispatcherTypes = false
+            authorize(anyRequest, authenticated)
+        }
+    }
+    return http.build()
+}
+----
 ====