在SecurityFilter中调用getUserPrincipal导致IllegalStateException:握手未完成

时间:2013-01-08 14:14:29

标签: https jersey grizzly userprincipal

我只是尝试使用Jersey 1.16并在我的应用程序中添加https支持。 使用Jersey https_grizzly example作为参考,我在SecurityFilter.authority()中添加了一行代码

final Principal principal = request.getSecurityContext().getUserPrincipal();
if (principal != null){
    System.out.println("principal: " + principal.getName());
} else {
System.out.println("No principal") ;
}

然后我尝试使用https和setNeedClientAuth启动服务器为false,以避免在startServer()中更改Server.java来使用客户端证书:

webServer = GrizzlyServerFactory.createHttpServer(
                getBaseURI(),
                null,
                true,
                new SSLEngineConfigurator(sslContext).setClientMode(false).setNeedClientAuth(false)
        );

setNeedClientAuth(false)中的boolean参数最初为true,以便请求客户端证书。 我认为通过这种方式,我的应用程序可以适应客户端,无论是否有证书。没有证书时,getUserPrincipal()可能会返回null,以便我知道这是一个匿名用户。 不幸的是,在这种情况下,系统会引发异常,并且客户端什么也没收到:

java.lang.IllegalStateException: Handshake is not completed!
at org.glassfish.grizzly.ssl.SSLFilter.accurateWrite(SSLFilter.java:569)
at org.glassfish.grizzly.ssl.SSLFilter.handleWrite(SSLFilter.java:216)
at org.glassfish.grizzly.filterchain.ExecutorResolver$8.execute(ExecutorResolver.java:111)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:265)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:200)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:134)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:78)
at org.glassfish.grizzly.filterchain.FilterChainContext.write(FilterChainContext.java:652)
at org.glassfish.grizzly.http.server.io.OutputBuffer.writeContentBuffer0(OutputBuffer.java:908)
at org.glassfish.grizzly.http.server.io.OutputBuffer.flushBinaryBuffers(OutputBuffer.java:893)
at org.glassfish.grizzly.http.server.io.OutputBuffer.flushAllBuffers(OutputBuffer.java:864)
at org.glassfish.grizzly.http.server.io.OutputBuffer.flush(OutputBuffer.java:678)
at org.glassfish.grizzly.http.server.NIOOutputStreamImpl.flush(NIOOutputStreamImpl.java:91)
at org.glassfish.grizzly.servlet.ServletOutputStreamImpl.flush(ServletOutputStreamImpl.java:101)
at com.sun.jersey.spi.container.servlet.WebComponent$Writer.flush(WebComponent.java:315)
at com.sun.jersey.spi.container.ContainerResponse$CommittingOutputStream.flush(ContainerResponse.java:145)
at sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:297)
at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:141)
at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:229)
at java.io.BufferedWriter.flush(BufferedWriter.java:254)
at com.sun.jersey.core.util.ReaderWriter.writeToAsString(ReaderWriter.java:191)
at com.sun.jersey.core.provider.AbstractMessageReaderWriterProvider.writeToAsString(AbstractMessageReaderWriterProvider.java:128)
at com.sun.jersey.core.impl.provider.entity.StringProvider.writeTo(StringProvider.java:88)
at com.sun.jersey.core.impl.provider.entity.StringProvider.writeTo(StringProvider.java:58)
at com.sun.jersey.spi.container.ContainerResponse.write(ContainerResponse.java:306)
at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1479)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1391)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1381)
at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:538)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:716)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
at org.glassfish.grizzly.servlet.FilterChainImpl.doFilter(FilterChainImpl.java:147)
at org.glassfish.grizzly.servlet.FilterChainImpl.invokeFilterChain(FilterChainImpl.java:106)
at org.glassfish.grizzly.servlet.ServletHandler.doServletService(ServletHandler.java:252)
at org.glassfish.grizzly.servlet.ServletHandler.service(ServletHandler.java:188)
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:164)
at org.glassfish.grizzly.http.server.HttpHandlerChain.service(HttpHandlerChain.java:196)
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:164)
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:175)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:265)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:200)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:134)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:78)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:815)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:115)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:55)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:135)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:567)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:547)
at java.lang.Thread.run(Thread.java:722)

为什么我在这种情况下无法使用getUserPrincipal()?有人知道吗?谢谢。

1 个答案:

答案 0 :(得分:2)

调用getUserPrincipal()将执行重新协商,请求客户端提供证书链。在这种情况下,ssl层引发了一个例外,即cert链为null,但是,Grizzly没有抛出异常(它可能应该)。因为它没有抛出它,所以SSLEngine处于不正确的状态,导致你上面描述的异常。

我已经记录issue以更好地处理此案例。