Question

I just tried to use Jersey 1.16 and add https support in my application. Using Jersey https_grizzly example as a reference, I added a line of code in the SecurityFilter.authority()

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

Then I tried to start the server using https and setNeedClientAuth to false to avoid using client side certificate by changing Server.java in startServer():

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

the boolean parameter in setNeedClientAuth(false) is originally true in order to request client certificate. I think in this way my application can adapt to client with and without a certificate. When without a certificate, the getUserPrincipal() may return null so that I know this is an anonymous user. Unfortunately, in this case, the system raises an exception as following and the client received nothing:

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)

Why I couldn't use getUserPrincipal() in this case? Does somebody know about it? Thank you.

Was it helpful?

Solution

Calling getUserPrincipal() will perform a renegotiation requesting that the client provide a certificate chain. In this case, the ssl layer is raising an exception that the cert chain is null, however, Grizzly isn't throwing the exception (and it probably should). Because it doesn't throw it, the SSLEngine is left an in incorrect state leading to the exception you have described above.

I've logged an issue to better handle this case.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top