我有一个JAX-RS过滤器使用ContainerRequestContext#abortWith(..)
来表示授权失败:
@Priority(Priorities.AUTHORIZATION)
public class RequirePrincipalFilter implements ContainerRequestFilter {
private static final Logger LOG = LoggerFactory
.getLogger(RequirePrincipalFilter.class);
@Override
public void filter(final ContainerRequestContext requestContext)
throws IOException {
if (requestContext.getSecurityContext() == null
|| requestContext.getSecurityContext().getUserPrincipal() == null) {
LOG.debug("No Principal");
requestContext.abortWith(Response
.status(Status.UNAUTHORIZED)
.entity(new ErrorRepresentation(Status.UNAUTHORIZED
.getStatusCode(), "Authorization required"))
.header("WWW-Authenticate", "Bearer").build());
LOG.debug("Request Aborted");
}
}
}
当连续发出请求以便调用abortWith(..)
时,
没有问题。但是,当发出两个或更多这样的请求时
同时,服务发散,使得不返回响应
和
连接挂起。对服务器的任何进一步请求
善良 - 通过过滤器授权,未经授权,甚至是请求
完全绕过过滤器 - 也导致挂起连接而没有响应。
为所有适用的abortWith(..)
调用两个日志语句
调用。即代码未挂起在方法调用上
本身。
我的问题是:我正确使用abortWith(..)
设施吗?
我怀疑我自己的错误 - 否则我希望有
发现有人遇到这个麻烦。
我在Grizzly2 HTTP容器中使用Jersey 2.17运行它,JVM是 Oracle JSE 1.8.0_45。我也尝试用JDK容器替换Grizzly容器。问题是一样的。
作为一项实验,我尝试将调用序列化为abortWith(..)
通过使用静态LOG作为监视器从同步块内调用它。即使调用序列化,问题仍然存在。