使用RouterFunction时Spring Security中Principal始终为null的问题
Spring WebFlux + RouterFunction 自定义Spring Security配置实现
刚好我在项目里经常用Spring WebFlux结合RouterFunction做无控制器的API服务,搭配自定义Spring Security配置的话,给你一个完整的实现示例和关键细节说明:
@Bean fun security(httpSecurity: ServerHttpSecurity): SecurityWebFilterChain { return httpSecurity // 指定自定义认证管理器,处理身份校验逻辑 .authenticationManager(authenticationManager) // 禁用API场景下不需要的默认安全组件 .httpBasic().disable() .formLogin().disable() .logout().disable() .csrf().disable() // 注入自定义认证过滤器,替换默认的认证流程 .addFilterAt(apiAuthenticationWebFilter(), SecurityWebFiltersOrder.AUTHENTICATION) // 配置路径级别的授权规则 .authorizeExchange() // 开放无需认证的公开路径(比如健康检查、公开接口) .pathMatchers("/actuator/health", "/api/public/**").permitAll() // 指定需要ADMIN角色才能访问的路径 .pathMatchers("/api/admin/**").hasRole("ADMIN") // 兜底规则:其余所有路径都需要经过认证才能访问 .anyExchange().authenticated() .and() .build() }
关键配置细节拆解
- 禁用默认安全组件:咱们做的是API服务,面向的是客户端而非浏览器,所以
httpBasic、formLogin这些传统的浏览器认证方式完全用不上,csrf防护也可以直接禁用(API一般用Token认证,不存在CSRF风险),这样能精简安全过滤链,避免不必要的拦截逻辑。 - 自定义认证过滤器:通过
addFilterAt把咱们的apiAuthenticationWebFilter放到SecurityWebFiltersOrder.AUTHENTICATION这个优先级位置,刚好替换掉Spring Security默认的认证逻辑。你可以在这个过滤器里实现JWT Token校验、自定义身份凭证解析等逻辑,完全贴合API的认证需求。 - 路径授权规则:这里一定要注意规则的顺序——更具体的路径要放在前面,否则会被后面的兜底规则覆盖:
- 先用
permitAll()开放完全公开的接口,比如健康检查、无需登录就能访问的公共API; - 然后给需要特定权限的路径绑定角色/权限,比如
/api/admin/**只允许拥有ADMIN角色的用户访问; - 最后用
anyExchange().authenticated()兜底,确保所有未明确配置的路径都必须经过认证才能访问。
- 先用
RouterFunction 搭配 Security 的注意事项
要保证Security的路径匹配规则和你用RouterFunction定义的API端点路径完全一致,比如Router里定义了
GET("/api/admin/users"),那Security里的/api/admin/**就能正确匹配到这个端点,避免出现权限配置失效的情况。
内容的提问来源于stack exchange,提问作者yyunikov
相关产品推荐
相关产品推荐

