我正在尝试设置多个安全配置,这些配置将使用基于SecurityApiKeyFilter的不同pathMatchers类,目前我只得到了两个,一个用于所有URL,另一个只在包含admin的URL上工作。最初,您被设置为来宾,之后,我们将尝试基于ApiKey授权您。然而,我不能真正让它达到第二SecurityWebFilterChain配置。即使pathMatcher是这样设置的。
@Bean
@Order(1)
public SecurityWebFilterChain securitygWebFilterChain(ServerHttpSecurity http,
ClientService clientService) {
SecurityWebFilterChain filterChain = http.authorizeExchange()
.pathMatchers(HttpMethod.GET, "/").permitAll()
.pathMatchers(HttpMethod.OPTIONS, "/**").permitAll()
.pathMatchers("/**").permitAll()
.anyExchange().authenticated().and()
.anonymous().principal("guest").and()
.addFilterBefore(new SecurityApiKeyFilter(clientService), SecurityWebFiltersOrder.AUTHENTICATION)
.oauth2ResourceServer().jwt()
.jwtDecoder(new NimbusReactiveJwtDecoder("/.well-known/jwks.json"))
.and()
.and().build();
return filterChain;
}
@Bean
@Order(2)
public SecurityWebFilterChain sdkJsWebFilterChain(ServerHttpSecurity http,
ClientService clientService) {
SecurityWebFilterChain filterChain = http.authorizeExchange()
.pathMatchers(HttpMethod.OPTIONS, "**/admin/**").permitAll()
.pathMatchers("**/admin/**").permitAll()
.anyExchange().authenticated().and()
.anonymous().principal("guest").and()
.addFilterBefore(new Admin.SecurityApiKeyFilter(clientService),
SecurityWebFiltersOrder.AUTHENTICATION)
.oauth2ResourceServer().jwt()
.jwtDecoder(new NimbusReactiveJwtDecoder("/.well-known/jwks.json"))
.and()
.and().build();
return filterChain;
}谢谢。
发布于 2021-03-31 08:50:36
我想,对于反应性应用程序来说,这与servlet应用程序是一样的。
不执行第二个安全筛选链,因为只有第一个匹配的安全筛选链将被调用,请参阅9.4.SecurityFilterChain。
9.4.SecurityFilterChain ..。 实际上,可以使用
FilterChainProxy来确定应该使用哪个SecurityFilterChain。这允许为应用程序的不同部分提供完全独立的配置。

在多个SecurityFilterChain图中,FilterChainProxy决定应该使用哪个SecurityFilterChain。只有匹配的第一个SecurityFilterChain将被调用。如果请求/api/messages/的URL,它将首先与SecurityFilterChain0的/api/**模式匹配,因此即使在SecurityFilterChainn上也匹配,也只会调用SecurityFilterChain0。如果请求/messages/的URL,它将不匹配SecurityFilterChain0的/api/**模式,因此FilterChainProxy将继续尝试每个SecurityFilterChain。假设不调用其他的SecurityFilterChain实例,则将调用SecurityFilterChainn。
发布于 2021-04-01 07:55:30
我还发现这非常有用,以防有人在寻找另一种类型的解决方案--它不是用Java编写的,但是您会得到要点的。
class SecurityConfig {
@Bean
fun getReactiveAuthenticationManager(): ReactiveAuthenticationManager {
return ReactiveAuthenticationManager { authentication ->
// simply return the authentication assuming the authentication was already verified in the converter
Mono.justOrEmpty(authentication)
}
}
companion object {
const val ADMIN_RESOURCE_A = "ADMIN_RESOURCE_A"
const val ADMIN_RESOURCE_B = "ADMIN_RESOURCE_B"
}
@Bean
fun springSecurityFilterChain(http: ServerHttpSecurity,
@Qualifier("authFilterResourceA")
authFilterResourceA: AuthenticationWebFilter,
@Qualifier("authFilterResourceB")
authFilterResourceB: AuthenticationWebFilter): SecurityWebFilterChain {
//configure security for resource a
http
.addFilterAt(authFilterResourceA, SecurityWebFiltersOrder.AUTHENTICATION)
.authorizeExchange()
.pathMatchers("/resourceA/**")
.hasRole(ADMIN_RESOURCE_A)
//configure security for resource b
http
.addFilterAt(authFilterResourceB, SecurityWebFiltersOrder.AUTHENTICATION)
.authorizeExchange()
.pathMatchers("/resourceB/**")
.hasRole(ADMIN_RESOURCE_B)
// global config
http
.httpBasic()
.disable()
.formLogin()
.disable()
.csrf()
.disable()
.cors()
.disable()
.authorizeExchange()
.anyExchange()
.authenticated()
return http.build()
}
@Bean("authFilterResourceA")
fun authFilterResourceA(authManager: ReactiveAuthenticationManager): AuthenticationWebFilter {
val filter = AuthenticationWebFilter(authManager)
filter.setServerAuthenticationConverter {
// simplified dummy token conversion for keeping the example as simple as possible
Mono.justOrEmpty(it)
.map { it.request.headers.getFirst("X-Application-Authentication") ?: "" }
.filter { it == "Bearer tokenForA" }
.map {
val authentication = UsernamePasswordAuthenticationToken(
"userWithAccessRightsToA",
it,
listOf(SimpleGrantedAuthority("ROLE_$ADMIN_RESOURCE_A"))
)
logger.info { "Created authentication: $authentication" }
authentication as Authentication
}
}
return filter
}
@Bean("authFilterResourceB")
fun authFilterResourceB(authManager: ReactiveAuthenticationManager): AuthenticationWebFilter {
val filter = AuthenticationWebFilter(authManager)
filter.setServerAuthenticationConverter {
// simplified dummy token conversion for keeping the example as simple as possible
Mono.justOrEmpty(it)
.map { it.request.headers.getFirst("X-Application-Authentication") ?: "" }
.filter { it == "Bearer tokenForB" }
.map {
val authentication = UsernamePasswordAuthenticationToken(
"userWithAccessRightsToB",
it,
listOf(SimpleGrantedAuthority("ROLE_$ADMIN_RESOURCE_B"))
)
logger.info { "Created authentication: $authentication" }
authentication as Authentication
}
}
return filter
}发布于 2022-08-20 18:57:39
如果您想要将路径模式与其他安全web筛选链完全分离,可以使用如下所示的SecurityWebFilterChain来配置多个securityMatcher。
public SecurityWebFilterChain stackSagaEndpoint(ServerHttpSecurity http) {
http.securityMatcher(new PathPatternParserServerWebExchangeMatcher("/specific -path/**"))
....
}执行将取决于您的进一步配置,如排序和全局配置。
https://stackoverflow.com/questions/66883174
复制相似问题