在Spring Webflux中如何在端点执行前创建并持久化自定义用户对象
实现方案
你可以通过自定义一个Spring WebFilter,在认证逻辑执行完成后自动完成用户存在性校验和创建操作,不需要修改现有接口代码。
1. 实现自定义自动创建用户过滤器
import org.springframework.core.Ordered import org.springframework.core.annotation.Order import org.springframework.security.core.context.ReactiveSecurityContextHolder import org.springframework.stereotype.Component import org.springframework.web.server.ServerWebExchange import org.springframework.web.server.WebFilter import org.springframework.web.server.WebFilterChain import reactor.core.publisher.Mono import java.time.LocalDateTime // 配置优先级保证在Spring Security认证过滤器之后执行 @Component @Order(Ordered.HIGHEST_PRECEDENCE + 10) class UserAutoCreateFilter( // 替换为你自己项目的反应式用户Repository private val userRepository: UserRepository ) : WebFilter { override fun filter(exchange: ServerWebExchange, chain: WebFilterChain): Mono<Void> { // 只处理/secure路径下的已认证请求,避免不必要的数据库查询 val requestPath = exchange.request.uri.path if (!requestPath.startsWith("/secure/")) { return chain.filter(exchange) } return ReactiveSecurityContextHolder.getContext() .map { it.authentication } // 过滤未认证、匿名的请求 .filter { it.isAuthenticated && it.name != null && !"anonymousUser".equals(it.name) } .flatMap { auth -> val userOAuthUuid = auth.name // 校验用户是否已存在 userRepository.existsByUuid(userOAuthUuid) .filter { exists -> !exists } .flatMap { // 首次访问则创建新用户 // 若需要更多用户属性,可以将auth强转为JwtAuthenticationToken,从JWT的Claims中获取 // val jwt = auth as JwtAuthenticationToken // val email = jwt.token.getClaimAsString("email") val newUser = User( uuid = userOAuthUuid, createTime = LocalDateTime.now() // 补充其他需要的用户字段 ) userRepository.save(newUser) } } // 无论用户是否是首次访问,都继续执行后续接口逻辑 .then(chain.filter(exchange)) } }
2. 注意事项
- 这里用到的
UserRepository必须是反应式实现(比如继承R2dbcRepository),不能使用阻塞的JDBC/JPA实现,否则会在Webflux环境下抛出线程阻塞异常。 - 过滤器加了
@Component注解后会自动全局生效,无需额外注册,如果你希望手动注册到Spring Security过滤链中,也可以在springSecurityFilterChain方法中通过http.addFilterAfter()方法添加。
内容的提问来源于stack exchange,提问作者d35t1201
相关产品推荐
相关产品推荐

