2014-09-08 3 views
0

봇 클라이언트와 서버 인증을 사용하여 https 리 스타렛을 구현할 수있었습니다. 신뢰할 수없는 인증 통신을 사용하여 서버에 전화를 걸면 작동하지 않는다는 것을 증명할 수 있습니다. 불행히도 서버에서 클라이언트의 인증서를 찾을 수 없습니다. 이 코드를 사용하고 있습니다 :리셀러에서 클라이언트 인증서 받기

List<Certificate> certs = request.getClientInfo().getCertificates(); 

그러나 목록이 비어 있습니다. 내가 뭘 잘못하고있어?

편집 :

버전입니다 이 방법은 당신이 찾고있는 무엇을 제공해야한다

+0

이 사람은 2.1로 업그레이드되어 동일한 문제가있었습니다. 답변 없음 : (http://stackoverflow.com/questions/13048855/restlet-2-1-cant-get-client-certificate – tom

+0

request.getAttributes() .. get ("org.restlet.https.clientCertificates") 않습니다. ; 작동합니까? – tom

+0

@tom 불행히도 그것은 작동하지 않습니다. AFAIK getCerificates에 의해 수행 된 호출은 해당 특성을 사용합니다. –

답변

-1

으로 Restlet 프레임 워크/2.3m2 :. request.getClientInfo()의 getCertificates() http://restlet.com/learn/javadocs/2.3/jse/api/org/restlet/data/ClientInfo.html

암호 모음을 검색 할 수도 있습니다.

+0

OP에서 볼 수 있듯이 게시하는 코드는 정확하게 내가 사용하지만 작동하지 않습니다. 나는 자기가 재주문을 호스팅하고 있는데, 이것이 문제가 될 수 있습니까? –

+0

어느 컨테이너를 사용하고 있습니까, 부두인가, 바람둥이입니까? – tom

+0

@tom 나는 http 청취를 자체 호스팅하고있다. 즉, 듣기 위해 restlet을 사용한다. –

1

문제는 d 오류 서버 구현은 com.sun.httpserver입니다. 클래스 org.restlet.engine.connector.HttpExchangeCall은 메서드의 인증서를 반환해야하지만 항상 null을 반환합니다. 이 클래스는 org.restlet.engine.connector.HttpsServerHelper 에서 사용되며 서버 구현 com.sun.httpserver을 사용할 때 Restlet 프레임 워크의 도우미입니다.

이 문제를 해결하려면 몇 가지 작업이 필요합니다.
첫째, 새로운 클래스 HttpsExchangeCall :

package org.restlet.engine.connector; 

import java.security.cert.Certificate; 
import java.util.ArrayList; 
import java.util.List; 

import org.restlet.Server; 
import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 

import com.sun.net.httpserver.HttpExchange; 
import com.sun.net.httpserver.HttpsExchange; 

/** 
* The default {@link HttpExchangeCall} fails to extract certificates from the SSL connection. 
* This class implements {@link #getCertificates()} to extract certificates. 
*/ 
@SuppressWarnings("restriction") 
public class HttpsExchangeCall extends HttpExchangeCall { 

    private static final Logger log = LoggerFactory.getLogger(HttpsExchangeCall.class); 

    private final HttpsExchange sexchange; 

    public HttpsExchangeCall(Server server, HttpExchange exchange) { 
     this(server, exchange, true); 
    } 

    public HttpsExchangeCall(Server server, HttpExchange exchange, boolean confidential) { 
     super(server, exchange, confidential); 
     if (exchange instanceof HttpsExchange) { 
      sexchange = (HttpsExchange) exchange; 
     } else { 
      sexchange = null; 
     } 
    } 

    @Override 
    public List<Certificate> getCertificates() { 

     if (sexchange == null) { 
      log.debug("Cannot extract peer certificates from unsecure connection."); 
      return null; 
     } 
     Certificate[] certs = null; 
     try { 
      certs = sexchange.getSSLSession().getPeerCertificates(); 
      if (log.isDebugEnabled()) { 
       log.debug("Found " + (certs == null ? "no" : Integer.toString(certs.length)) + " peer certificate(s)."); 
      } 
     } catch (Exception e) { 
      log.debug("Unable to find peer certificates - " + e); 
     } 
     List<Certificate> lcerts = null; 
     if (certs != null) { 
      lcerts = new ArrayList<Certificate>(); 
      for (int i = 0; i < certs.length; i++) { 
       lcerts.add(certs[i]); 
      } 
     } 
     return lcerts; 
    } 

} 

그런 다음 수정 한 라인으로 HttpsServerHelper2로 이름이 변경 HttpsServerHelper 의 사본. 라인과 라인
HttpsServerHelper.this.handle(new HttpExchangeCall(getHelped(),
교체 :
HttpsServerHelper2.this.handle(new HttpsExchangeCall(getHelped(),

이 헬퍼를 등록 할 필요가있다 :
Engine.getInstance().getRegisteredServers().add(new HttpsServerHelper2(null));
지금은 Server을 만드는 매우 명시된다 :

Component component = new Component(); 
Server server = new Server(
     (Context) null, Arrays.asList(Protocol.HTTPS), 
     (String) null, Constants.PORT_TEST, component.getServers().getNext(), 
     HttpsServerHelper2.class.getName() 
    ); 
component.getServers().add(server); 

난 희망하는 Restlet 자신의 HttpExchangeCall은 인증서를 추출하기 위해 업데이트됩니다 : is is 사소한 문제를 해결하고 문제를 해결하는 데 필요한 많은 불필요한 코드를 절약 할 수 있습니다.
한편, Github 프로젝트의 restlet-clientcert에서 모든 소스 코드 (Restlet 2.3.4 사용)와 작동 예제를 찾을 수 있습니다.