首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于pathMatcher添加多个Spring安全配置

基于pathMatcher添加多个Spring安全配置
EN

Stack Overflow用户
提问于 2021-03-31 07:06:12
回答 3查看 3.3K关注 0票数 3

我正在尝试设置多个安全配置,这些配置将使用基于SecurityApiKeyFilter的不同pathMatchers类,目前我只得到了两个,一个用于所有URL,另一个只在包含admin的URL上工作。最初,您被设置为来宾,之后,我们将尝试基于ApiKey授权您。然而,我不能真正让它达到第二SecurityWebFilterChain配置。即使pathMatcher是这样设置的。

代码语言:javascript
复制
@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;
}

谢谢。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 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

票数 3
EN

Stack Overflow用户

发布于 2021-04-01 07:55:30

我还发现这非常有用,以防有人在寻找另一种类型的解决方案--它不是用Java编写的,但是您会得到要点的。

代码语言:javascript
复制
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
}

来源:https://github.com/jimonthebarn/spring-webflux-multiple-auth-mechanisms/blob/master/src/main/kotlin/localhost/playground/multi/auth/SecurityConfig.kt

票数 0
EN

Stack Overflow用户

发布于 2022-08-20 18:57:39

如果您想要将路径模式与其他安全web筛选链完全分离,可以使用如下所示的SecurityWebFilterChain来配置多个securityMatcher

代码语言:javascript
复制
public SecurityWebFilterChain stackSagaEndpoint(ServerHttpSecurity http) {

   http.securityMatcher(new PathPatternParserServerWebExchangeMatcher("/specific -path/**"))
   ....

}

执行将取决于您的进一步配置,如排序和全局配置。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66883174

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档