Spring WebFlux Security - 是不是可以在 SecurityWebFilterChain 上为不同的资源配置多个 ServerAuthenticationEntryPoints

Posted

技术标签:

【中文标题】Spring WebFlux Security - 是不是可以在 SecurityWebFilterChain 上为不同的资源配置多个 ServerAuthenticationEntryPoints【英文标题】:Spring WebFlux Security - Is it possible to configure multiple ServerAuthenticationEntryPoints on a SecurityWebFilterChain for different resourcesSpring WebFlux Security - 是否可以在 SecurityWebFilterChain 上为不同的资源配置多个 ServerAuthenticationEntryPoints 【发布时间】:2020-07-03 02:24:42 【问题描述】:

我的 spring webflux 应用程序中有几个不同的 API,它们需要对失败的身份验证做出不同的响应。我正在尝试为每个 API 设置不同的 ServerAuthenticationEntryPoints 来处理这些情况。

我发现 this 示例配置显示了如何为不同的资源配置不同的 AuthenticationWebFilter,这使您可以单独设置 ServerAuthenticationSuccessHandler 和 ServerAuthenticationFailureHandler,但是我不确定如何在没有完全独立的 SecurityWebFilterChains 的情况下配置不同的 ServerAuthenticationEntryPoints。

如果我必须配置单独的 SecurityWebFilterChains,我该怎么做?

我的 SecurityWebFilterChain 目前是这样配置的 - 不幸的是,您不能单独设置 exceptionHandling,并且第二次调用 authenticationEntryPoint 是先例:

@Bean
fun securityWebFilterChain(
    http: ServerHttpSecurity,
    userServerAuthenticationEntryPoint: ServerAuthenticationEntryPoint,
    userAuthenticationWebFilter: AuthenticationWebFilter,
    deviceServerAuthenticationEntryPoint: ServerAuthenticationEntryPoint,
    deviceAuthenticationWebFilter: AuthenticationWebFilter,
    serverSecurityContextRepository: ServerSecurityContextRepository,
    authenticationManager: ReactiveAuthenticationManager,
    serverAccessDeniedHandler: ServerAccessDeniedHandler
): SecurityWebFilterChain 
    http
        .addFilterAt(userAuthenticationWebFilter, SecurityWebFiltersOrder.AUTHENTICATION)
        .exceptionHandling()
            .authenticationEntryPoint(userServerAuthenticationEntryPoint)
            .and()
        .authorizeExchange()
            .pathMatchers(GET, "/sign-in").permitAll()
            .pathMatchers("/authentication/**").permitAll()
            .pathMatchers(GET, "/landing").hasAnyAuthority("USER", "ADMIN")
            .pathMatchers("/user-api/**").hasAnyAuthority("USER", "ADMIN")

    http
        .addFilterAt(deviceAuthenticationWebFilter, SecurityWebFiltersOrder.AUTHENTICATION)
        .exceptionHandling()
            .authenticationEntryPoint(deviceServerAuthenticationEntryPoint)
            .and()
        .authorizeExchange()
            .pathMatchers("/device-api/**").hasAuthority("DEVICE")

    // GLOBAL
    http
        .httpBasic().disable()
        .formLogin().disable()
        .csrf().disable()
        .cors().disable()
        .securityContextRepository(serverSecurityContextRepository)
        .authenticationManager(authenticationManager)
        .exceptionHandling()
            .accessDeniedHandler(serverAccessDeniedHandler)
            .and()
        .authorizeExchange()
            .pathMatchers(GET, "/webjars/**").permitAll()
            .pathMatchers(GET, "/assets/**").permitAll()
            .anyExchange().authenticated()

    return http.build()

【问题讨论】:

您可以根据请求 url 模式添加多个入口点。例如,参见baeldung.com/spring-security-multiple-entry-points 的第 3.2 节 @Ritesh 对于常规 Spring MVC 应用程序来说是正确的,但是 Spring Webflux ServerHttpSecurity 的 ExceptionHandlingSpec 不允许选择性异常处理(据我所知) 你说得对,这篇文章不是针对 webflux 的,我也没有在 webflux 中使用过多个入口点。查看代码ServerHttpSecurity,它似乎将defaultEntryPoints 作为DelegateEntry 的列表,并且默认设置了RedirectServerAuthenticationEntryPoint 是的,应该可以。您可以使用 ServerWebExchangeMatchers 对其进行限制。谢谢。 【参考方案1】:

事实证明,默认的 ServerAuthenticationEntryPoint 是 DelegatingServerAuthenticationEntryPoint,它使您能够通过 ServerWebExchangeMatchers 配置哪个实际入口点负责任何给定的 ServerWebExchange。见this comment。

【讨论】:

您能否分享您对问题的最终解决方案的代码?

以上是关于Spring WebFlux Security - 是不是可以在 SecurityWebFilterChain 上为不同的资源配置多个 ServerAuthenticationEntryPoints的主要内容,如果未能解决你的问题,请参考以下文章

WebFlux Spring Security配置

Spring Webflux Security 中的角色层次结构

将 spring-security 与 spring-webflux 一起使用时禁用 WebSession 创建

在 Spring WebFlux 中使用 Spring Security 实现身份验证的资源是啥

Spring WebFlux + Security - 我们有“记住我”功能吗?

如何在 Spring WebFlux Security(Reactive Spring Security)配置中将多个用户角色添加到单个 pathMatcher/Route?