在restlet中获取客户端证书 [英] Getting client certificate in restlet
问题描述
我设法实现了一个带有 bot 客户端和服务器认证的 https restlet.我可以证明它有效,因为如果我使用不受信任的认证通信调用服务器会失败.不幸的是,我在服务器上找不到客户端的证书.我正在使用此代码:
I managed to implement an https restlet with bot client and server certificated. I can prove it works since if I call the server with an untrusted certification communication fails. Unfortunately I can't find the certificate of the client on the server. I'm using this code:
List<Certificate> certs = request.getClientInfo().getCertificates();
但列表为空.我做错了什么?
but list is empty. What I'm doing wrong?
编辑:
版本是 Restlet-Framework/2.3m2
推荐答案
该问题与通过 com.sun.httpserver
使用默认服务器实现有关.org.restlet.engine.connector.HttpExchangeCall
类应该在 getCertificates()
方法中返回证书,但它总是返回 null
.该类在org.restlet.engine.connector.HttpsServerHelper
中使用在使用服务器实现 com.sun.httpserver
时,它又是 Restlet 框架的助手.
The problem is related to the use of the default server implementation via com.sun.httpserver
.
The class org.restlet.engine.connector.HttpExchangeCall
should return the certificates in the getCertificates()
method,
but it always returns null
. This class is used in org.restlet.engine.connector.HttpsServerHelper
which in turn is the helper for the Restlet framework when using the server implementation com.sun.httpserver
.
要解决这个问题,需要做一些事情.
首先,一个新类HttpsExchangeCall
:
To fix this, a couple of things are needed.
First, a new class 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;
}
}
然后是HttpsServerHelper改名为 HttpsServerHelper2
并修改了一行.更换线路HttpsServerHelper.this.handle(new HttpExchangeCall(getHelped(),
与线:HttpsServerHelper2.this.handle(new HttpsExchangeCall(getHelped(),
Then a copy of HttpsServerHelper
renamed to HttpsServerHelper2
with one line modified. Replace the line
HttpsServerHelper.this.handle(new HttpExchangeCall(getHelped(),
with the line:
HttpsServerHelper2.this.handle(new HttpsExchangeCall(getHelped(),
这个助手需要注册:Engine.getInstance().getRegisteredServers().add(new HttpsServerHelper2(null));
并且创建一个Server
现在变得非常明确:
This helper needs to be registered:
Engine.getInstance().getRegisteredServers().add(new HttpsServerHelper2(null));
and creating a Server
now becomes very explicit:
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
将被更新以提取证书:这是一个小修复,并节省了解决该问题所需的大量不需要的代码.
同时,您可以在以下目录中找到所有源代码(使用 Restlet 2.3.4)和一个工作示例restlet-clientcert Github 项目.
I'm hoping Restlet's own HttpExchangeCall
will be updated to extract the certificates:
it is a minor fix and saves a lot of unneeded code required to work around the issue.
In the mean time, you can find all the source code (using Restlet 2.3.4) and a working example in the
restlet-clientcert Github project.
这篇关于在restlet中获取客户端证书的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!