You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Webflux如何配置特定路径用HTTP Basic其余路径用JWT认证

实现思路

和Spring MVC的多配置逻辑一致,WebFlux安全体系也支持注册多个SecurityWebFilterChain Bean,通过@Order指定执行优先级即可:高优先级配置仅匹配/actuator/**路径,单独走HTTP Basic认证;低优先级配置处理剩余所有业务接口,复用原有JWT认证逻辑。

完整实现代码

import org.springframework.beans.factory.annotation.Value
import org.springframework.boot.autoconfigure.security.SecurityProperties
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.core.Ordered
import org.springframework.core.annotation.Order
import org.springframework.http.HttpMethod
import org.springframework.security.config.annotation.method.configuration.EnableReactiveMethodSecurity
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity
import org.springframework.security.config.web.server.ServerHttpSecurity
import org.springframework.security.core.userdetails.MapReactiveUserDetailsService
import org.springframework.security.core.userdetails.User
import org.springframework.security.crypto.argon2.Argon2PasswordEncoder
import org.springframework.security.crypto.password.PasswordEncoder
import org.springframework.security.oauth2.server.resource.authentication.ReactiveJwtAuthenticationConverter
import org.springframework.security.web.server.SecurityWebFilterChain
import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatchers

@EnableWebFluxSecurity
@EnableReactiveMethodSecurity
class SecurityConfig(
    val userService: UserService,
    // 注入配置项,可根据实际情况调整
    @Value("\${management.endpoints.web.base-path:/actuator}")
    val managementPath: String,
    @Value("\${config.actuator.user.name}")
    val actuatorUser: String,
    @Value("\${config.actuator.user.password}")
    val actuatorPassword: String
) {

    /**
     * 高优先级配置:仅处理Actuator端点,走HTTP Basic认证
     * Order数值越小优先级越高,此处设为最高优先级
     */
    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    fun actuatorSecurityFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
        return http {
            // 限定仅匹配actuator所有路径,不拦截其他业务接口
            securityMatcher(ServerWebExchangeMatchers.pathMatchers("$managementPath/**"))
            csrf { disable() }
            formLogin { disable() }
            // 开启HTTP Basic认证
            httpBasic { }
            authorizeExchange {
                // 所有actuator端点需要有ACTUATOR角色才能访问
                authorize(anyExchange, hasRole("ACTUATOR"))
            }
            // 禁用当前链的JWT认证,避免和Basic认证冲突
            oauth2ResourceServer { disable() }
        }
    }

    /**
     * 低优先级配置:处理所有业务接口,走原有JWT认证逻辑
     */
    @Bean
    @Order(SecurityProperties.BASIC_AUTH_ORDER)
    fun apiSecurityFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
        return http {
            csrf { disable() }
            formLogin { disable() }
            httpBasic { disable() }
            authorizeExchange {
                authorize(ServerWebExchangeMatchers.pathMatchers(HttpMethod.OPTIONS, "/**"), permitAll)
                authorize(anyExchange, authenticated)
            }
            oauth2ResourceServer {
                jwt {
                    jwtAuthenticationConverter = customConverter()
                }
            }
        }
    }

    /**
     * 响应式内存用户存储,存储Actuator专用认证账号
     */
    @Bean
    fun actuatorUserDetailsService(passwordEncoder: PasswordEncoder): MapReactiveUserDetailsService {
        val actuatorAccount = User.withUsername(actuatorUser)
            .password(passwordEncoder.encode(actuatorPassword))
            .roles("ACTUATOR")
            .build()
        return MapReactiveUserDetailsService(actuatorAccount)
    }

    /**
     * 密码编码器,和原有MVC逻辑保持一致使用Argon2
     */
    @Bean
    fun passwordEncoder(): PasswordEncoder = Argon2PasswordEncoder()

    // 原有JWT转换逻辑保持不变即可
    private fun customConverter(): ReactiveJwtAuthenticationConverter {
        // 原有实现逻辑
    }
}

关键注意事项

  • 高优先级的Actuator配置必须加securityMatcher限定匹配路径,否则会拦截所有请求
  • WebFlux下的内存用户实现为MapReactiveUserDetailsService,不可使用MVC体系下的非响应式用户存储组件
  • 若需要开放部分actuator端点(如健康检查),可在Actuator配置的authorizeExchange中单独配置permitAll规则

内容的提问来源于stack exchange,提问作者Stuck

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.10 17:24:01