2013-01-08 2 views
2

Jersey 1.16을 사용하고 응용 프로그램에서 https 지원을 추가하려고했습니다. 참고로 Jersey https_grizzly example 사용 , 난 SecurityFilter에서 getUserPrincipal을 호출하면 IllegalStateException이 발생합니다. 핸드 쉐이크가 완료되지 않았습니다.

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

그럼 I 서버를 변경하여 클라이언트 측에서 인증서를 사용하지 거짓 HTTPS 및 setNeedClientAuth를 사용하여 서버를 시작하려()를 SecurityFilter.authority 코드의 라인을 추가했다. 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 계층에서 cert chain이 null이라는 예외를 발생 시키지만 Grizzly는 예외를 throw하지 않습니다 (아마도 그렇게해야합니다). 그것이 throw하지 않기 때문에, SSLEngine는 부정한 상태가되어, 전술 한 예외가 생깁니다.

이 케이스를보다 잘 처리하기 위해 issue을 기록했습니다.

+0

설명해 주셔서 감사합니다. 그러면 needClientAuth = false 인 경우 클라이언트 쪽에서 인증서가 있는지 여부를 어떻게 알 수 있습니까? – syan

+0

좋은 질문입니다. 이 문제는 수년간 존재 해왔다. 나는 당신이이 문제를 열어 줄 것을 요청하고 우리는 그곳에서 토론을 계속할 수 있습니다. – rlubke

+0

조언 해 주셔서 감사합니다. 나는 새로운 문제 [여기]를 만들었습니다. (http://stackoverflow.com/questions/14280008/how-can-i-find-out-if-the-client-has-a-certificate-in-case-of- needclientauth-fal). – syan

관련 문제