这段代码是一个基于Spring WebFlux框架的拦截器(或过滤器)实现,用于处理请求的认证和授权逻辑。
业务中常见代码
这个过滤器的核心目标是对每个HTTP请求进行拦截,验证用户身份并检查访问权限。它采用了典型的"先放行公开路径,再验证需授权路径"的策略,遵循以下步骤:
ServerHttpRequest request = exchange.getRequest();
String method = request.getMethodValue();
String path = request.getPath().toString();
String antPath = method + ":" + path;
ServerWebExchange
是WebFlux中表示HTTP请求-响应交换的核心接口if(isExcludePath(antPath)){
return chain.filter(exchange);
}
isExcludePath
是一个自定义方法,用于判断当前请求是否属于无需认证的路径列表List<String> authHeaders = exchange.getRequest().getHeaders().get(AUTHORIZATION_HEADER);
String token = authHeaders == null ? "" : authHeaders.get(0);
R<LoginUserDTO> r = authUtil.parseToken(token);
Authorization
字段,通常格式为 Bearer <token>
authUtil.parseToken
是自定义工具方法,用于验证token的有效性并解析用户信息R<LoginUserDTO>
是自定义的响应结果类,包含操作结果和用户数据if(r.success()){
exchange.mutate()
.request(builder -> builder.header(USER_HEADER, r.getData().getUserId().toString()))
.build();
}
ServerWebExchange.mutate()
方法修改请求,添加一个自定义请求头(如 X-User-Id
)authUtil.checkAuth(antPath, r);
authUtil.checkAuth
是自定义的权限检查方法AccessDeniedException
),由全局异常处理器统一处理return chain.filter(exchange);
FilterChain
的 filter
方法将请求传递给下一个过滤器或最终处理程序这段代码有一个潜在的问题:在第4步修改请求头后,没有将修改后的 ServerWebExchange
赋值回变量。正确的写法应该是:
if(r.success()){
ServerWebExchange mutatedExchange = exchange.mutate()
.request(builder -> builder.header(USER_HEADER, r.getData().getUserId().toString()))
.build();
return chain.filter(mutatedExchange);
}
否则修改的请求头不会生效,后续组件无法获取用户信息。
这个过滤器实现了一个完整的认证授权流程,通过拦截所有请求,区分公开路径和受保护路径,验证用户身份并检查访问权限,确保系统安全。它体现了Spring WebFlux的函数式编程风格和过滤器链设计模式。