在 Micronaut 过滤器中向传入请求添加 headers

Adding headers to incoming request in Micronaut filters

我正在编写一项服务,目前需要实现自己的 JWT 令牌验证。这稍后将由服务之前的层处理。

为此,我打算使用 HttpServerFilter 接口拦截请求:

@Filter(Filter.MATCH_ALL_PATTERN)
public class SecurityFilter implements HttpServerFilter {

    private static final Logger LOG = LoggerFactory.getLogger(SecurityFilter.class);

    @Override
    public Publisher<MutableHttpResponse<?>> doFilter(final HttpRequest<?> request, final ServerFilterChain chain) {
        return chain.proceed(request);
    }

    @Override
    public int getOrder() {
        return ServerFilterPhase.SECURITY.order();
    }

}

HttpFilter 界面状态:

To modify the request filters can either wrap it (using io.micronaut.http.HttpRequestWrapper or pass it along the chain as is

所以我尝试用这个 class:

来包装请求
final HttpRequestWrapper<?> wrappedRequest = new HttpRequestWrapper<>(request);
// wrappedRequest.getHeaders() Not mutable
// request.mutate().getHeaders() Mutable
// wrappedRequest.mutate().getHeaders() Mutable

但是,上面的两个 mutate 方法都在 HttpRequest 接口中使用相同的默认实现:

default MutableHttpRequest<B> mutate() {
    throw new UnsupportedOperationException("Request is immutable");
}

文档指出过滤器支持请求的装饰和响应的修改。这里装饰和修改有什么区别?

我想要的最终结果是我想解析一个 JWT 令牌,确保它有效,然后将令牌中的一个字段添加到新的 header 并从中检索 header控制器以下列方式:

@Get(uri = "/{id}", produces = MediaType.APPLICATION_JSON)
public Optional<Item> findById(@PathVariable("id") final String id, @Header("X-Tenant-Id") final String tenantId) {
    return service.findById(id, tenantId);
}

如何使用 Micronaut 过滤器实现此目的?

可以添加属性,而不是headers。属性最终实现相同的目的。

@Filter(Filter.MATCH_ALL_PATTERN)
public class SecurityFilter implements HttpServerFilter {

    public static final String TENANT_ID_ATTRIBUTE_NAME = "tenantId";

    private static final Logger LOG = LoggerFactory.getLogger(SecurityFilter.class);

    @Override
    public Publisher<MutableHttpResponse<?>> doFilter(final HttpRequest<?> request, final ServerFilterChain chain) {
        return chain.proceed(request.setAttribute(TENANT_ID_ATTRIBUTE_NAME, "tenantId"));
    }

    @Override
    public int getOrder() {
        return ServerFilterPhase.SECURITY.order();
    }

}

然后在控制器中:

@Get(produces = MediaType.APPLICATION_JSON)
public List<Item> list(@RequestAttribute(SecurityFilter.TENANT_ID_ATTRIBUTE_NAME) final String tenantId) {
    return service.findAll(tenantId);
}