2013-01-08 37 views
2

我剛剛嘗試使用Jersey 1.16並在我的應用程序中添加https支持。 使用Jersey https_grizzly example作爲參考,我添加的代碼行中SecurityFilter.authority()在SecurityFilter中調用getUserPrincipal導致IllegalStateException:握手未完成

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

然後我試圖使用HTTPS和setNeedClientAuth爲false,以避免通過改變服務器使用客戶端證書,以啓動服務器。在java中的startserver():

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

在setNeedClientAuth(假)的布爾參數最初是真正以請求客戶端證書。 我想這樣我的應用程序可以適應客戶端和沒有證書。如果沒有證書,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()?有人知道嗎?謝謝。

回答

2

調用getUserPrincipal()將執行重新協商,請求客戶端提供證書鏈。在這種情況下,ssl層會引發證書鏈爲空的異常,但是,Grizzly不會拋出異常(可能應該)。因爲它不會拋出它,所以SSLEngine處於不正確的狀態,導致上面描述的異常。

我已經登錄了issue以更好地處理這種情況。

+0

謝謝你的解釋。 那麼如何才能找出客戶端是否有證書或沒有needClientAuth = false的情況? – syan

+0

這是一個很好的問題。這種行爲已存在多年。我想要求您爲此提出問題,我們可以繼續討論。 – rlubke

+0

謝謝你的建議。我創建了一個新問題[here](http://stackoverflow.com/questions/14280008/how-can-i-find-out-if-the-client-has-a-certificate-in-case-of- needclientauth-FAL)。 – syan

相關問題