如何在Kotlin编写的Micronaut HttpServerFilter中返回Unauthorized
解决Micronaut HttpServerFilter返回Publisher的问题
你的过滤器逻辑是对的,但问题出在HttpResponse.unauthorized()返回的是单个响应对象,而doFilter方法要求返回响应式流的发布者(Publisher)。Micronaut默认使用Reactor作为响应式框架,你只需要把未授权的响应包装成Mono(单个元素的Publisher)即可。
修正后的完整代码
import io.micronaut.http.HttpRequest import io.micronaut.http.HttpResponse import io.micronaut.http.MutableHttpResponse import io.micronaut.http.filter.Filter import io.micronaut.http.filter.HttpServerFilter import io.micronaut.http.filter.ServerFilterChain import org.reactivestreams.Publisher import reactor.core.publisher.Mono import java.util.Base64 @Filter("/**") // 拦截所有请求路径,可根据需求调整 class APIKeyFilter : HttpServerFilter { override fun doFilter(request: HttpRequest<*>?, chain: ServerFilterChain?): Publisher<MutableHttpResponse<*>> { // 处理空请求或空链的边界情况,避免空指针 if (request == null || chain == null) { return Mono.just(HttpResponse.unauthorized()) } val apiKeyHeader = request.headers.get("X-API-Key") val expectedDecodedKey = "your-api-key".toByteArray() return if (apiKeyHeader == null || !Base64.getDecoder().decode(apiKeyHeader).contentEquals(expectedDecodedKey)) { // 将未授权响应包装为Publisher Mono.just(HttpResponse.unauthorized()) } else { // 验证通过,继续执行请求链 chain.proceed(request) } } }
关键说明
- 响应式包装:
Mono.just()是Reactor库提供的方法,用于创建包含单个元素的Publisher,完美适配方法返回值要求。 - 边界处理:增加了
request或chain为空的判断,避免运行时空指针异常,提升代码健壮性。 - 过滤器注册:通过
@Filter注解指定拦截路径,/**表示拦截所有请求,你也可以指定特定路径如/api/**来缩小拦截范围。
内容的提问来源于stack exchange,提问作者Dejan Vasic
相关产品推荐
相关产品推荐

