在Jetty服务器中,如何获取需要客户端身份验证时使用的客户端证书?

时间:2013-11-18 19:40:01

标签: java ssl embedded-jetty authentication

设置一个请求客户端身份验证的嵌入式Jetty服务器非常容易:只需添加该语句即可 SslContextFactory.setNeedClientAuth(真); 配置服务器时的ssl上下文。在服务器的信任库中拥有其证书的任何客户端都将能够与服务器建立TLS连接。

但是我需要知道所有可能的可信任客户端的哪个客户端正在发出请求;换句话说,我需要知道此连接中使用的客户端证书,特别是在处理程序中。有谁知道如何访问此证书或甚至可能?

2 个答案:

答案 0 :(得分:15)

Request HttpServletRequest将证书添加到HttpConfiguration个对象(例如Customizer)。

具体来说,SecureRequestCustomizer

您使用此代码的代码如下(向下滚动)...

Server server = new Server();

// === HTTP Configuration ===
HttpConfiguration http_config = new HttpConfiguration();
http_config.setSecureScheme("https");
http_config.setSecurePort(8443);
http_config.setOutputBufferSize(32768);
http_config.setRequestHeaderSize(8192);
http_config.setResponseHeaderSize(8192);
http_config.setSendServerVersion(true);
http_config.setSendDateHeader(false);

// === Add HTTP Connector ===
ServerConnector http = new ServerConnector(server,
    new HttpConnectionFactory(http_config));
http.setPort(8080);
http.setIdleTimeout(30000);
server.addConnector(http);

// === Configure SSL KeyStore, TrustStore, and Ciphers ===
SslContextFactory sslContextFactory = new SslContextFactory();
sslContextFactory.setKeyStorePath("/path/to/keystore");
sslContextFactory.setKeyStorePassword("changeme");
sslContextFactory.setKeyManagerPassword("changeme");
sslContextFactory.setTrustStorePath("/path/to/truststore");
sslContextFactory.setTrustStorePassword("changeme");
sslContextFactory.setExcludeCipherSuites(
      "SSL_RSA_WITH_DES_CBC_SHA",
      "SSL_DHE_RSA_WITH_DES_CBC_SHA",
      "SSL_DHE_DSS_WITH_DES_CBC_SHA",
      "SSL_RSA_EXPORT_WITH_RC4_40_MD5",
      "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
      "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
      "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA");

// === SSL HTTP Configuration ===
HttpConfiguration https_config = new HttpConfiguration(http_config);
https_config.addCustomizer(new SecureRequestCustomizer()); // <-- HERE

// == Add SSL Connector ===
ServerConnector sslConnector = new ServerConnector(server,
    new SslConnectionFactory(sslContextFactory,"http/1.1"),
    new HttpConnectionFactory(https_config));
sslConnector.setPort(8443);
server.addConnector(sslConnector);

使用此SecureRequestCustomizer,您可以使用以下属性名称从HttpServletRequest.getAttribute(String)调用访问有关SSL连接的各种部分。

<强> javax.servlet.request.X509Certificate

java.security.cert.X509Certificate []

的数组

<强> javax.servlet.request.cipher_suite

密码套件的String名称。 (与从javax.net.ssl.SSLSession.getCipherSuite()返回的内容相同)

<强> javax.servlet.request.key_size

使用密钥长度的整数

<强> javax.servlet.request.ssl_session_id

活动SSL会话ID的字符串表示(已经过化)

答案 1 :(得分:8)

有一个标准的servlet请求属性:javax.servlet.request.X509Certificate

它返回一个X509Certificates数组。

我们使用它来获取名称并从证书中查找DN:

x509Cert[0].getSubjectX500Principal().getName()