Explorar el Código

Add hasIpAddress to Reactive Kotlin DSL

Closes gh-10571
Steve Riesenberg hace 3 años
padre
commit
be802f57ba

+ 9 - 1
config/src/main/kotlin/org/springframework/security/config/web/server/AuthorizeExchangeDsl.kt

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2020 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -22,6 +22,7 @@ import org.springframework.security.authorization.AuthorizationDecision
 import org.springframework.security.authorization.ReactiveAuthorizationManager
 import org.springframework.security.core.Authentication
 import org.springframework.security.web.server.authorization.AuthorizationContext
+import org.springframework.security.web.server.authorization.IpAddressReactiveAuthorizationManager
 import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher
 import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatchers
 import org.springframework.security.web.util.matcher.RequestMatcher
@@ -108,6 +109,13 @@ class AuthorizeExchangeDsl {
     fun hasAnyAuthority(vararg authorities: String): ReactiveAuthorizationManager<AuthorizationContext> =
             AuthorityReactiveAuthorizationManager.hasAnyAuthority<AuthorizationContext>(*authorities)
 
+    /**
+     * Require a specific IP or range of IP addresses.
+     * @since 5.7
+     */
+    fun hasIpAddress(ipAddress: String): ReactiveAuthorizationManager<AuthorizationContext> =
+            IpAddressReactiveAuthorizationManager.hasIpAddress(ipAddress)
+
     /**
      * Require an authenticated user.
      */

+ 39 - 3
config/src/test/kotlin/org/springframework/security/config/web/server/AuthorizeExchangeDslTests.kt

@@ -22,16 +22,16 @@ import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.context.ApplicationContext
 import org.springframework.context.annotation.Bean
 import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity
-import org.springframework.security.core.userdetails.MapReactiveUserDetailsService
-import org.springframework.security.core.userdetails.User
 import org.springframework.security.config.test.SpringTestContext
 import org.springframework.security.config.test.SpringTestContextExtension
+import org.springframework.security.core.userdetails.MapReactiveUserDetailsService
+import org.springframework.security.core.userdetails.User
 import org.springframework.security.web.server.SecurityWebFilterChain
 import org.springframework.test.web.reactive.server.WebTestClient
 import org.springframework.web.bind.annotation.RequestMapping
 import org.springframework.web.bind.annotation.RestController
 import org.springframework.web.reactive.config.EnableWebFlux
-import java.util.*
+import java.util.Base64
 
 /**
  * Tests for [AuthorizeExchangeDsl]
@@ -181,4 +181,40 @@ class AuthorizeExchangeDslTests {
             return MapReactiveUserDetailsService(user)
         }
     }
+
+    @Test
+    fun `request when ip address does not match then responds with forbidden`() {
+        this.spring.register(HasIpAddressConfig::class.java).autowire()
+
+        this.client
+            .get()
+            .uri("/")
+            .header("Authorization", "Basic " + Base64.getEncoder().encodeToString("user:password".toByteArray()))
+            .exchange()
+            .expectStatus().isForbidden
+    }
+
+    @EnableWebFluxSecurity
+    @EnableWebFlux
+    open class HasIpAddressConfig {
+        @Bean
+        open fun springWebFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
+            return http {
+                authorizeExchange {
+                    authorize(anyExchange, hasIpAddress("10.0.0.0/24"))
+                }
+                httpBasic { }
+            }
+        }
+
+        @Bean
+        open fun userDetailsService(): MapReactiveUserDetailsService {
+            val user = User.withDefaultPasswordEncoder()
+                .username("user")
+                .password("password")
+                .roles("USER")
+                .build()
+            return MapReactiveUserDetailsService(user)
+        }
+    }
 }