-1

我正在编写一个服务,目前需要实现自己的 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界面说明:

要修改请求过滤器,可以包装它(使用 io.micronaut.http.HttpRequestWrapper 或按原样沿链传递

所以我尝试用这个类包装请求:

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 令牌,确保它是有效的,然后将一个字段从令牌添加到一个新的标头中,并通过以下方式从控制器中检索该标头:

@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 过滤器实现这一目标?

4

1 回答 1

0

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

@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);
}
于 2021-11-02T07:03:05.660 回答