【问题标题】:How can I access to certificate information如何访问证书信息
【发布时间】:2015-12-04 07:52:13
【问题描述】:

我有一个 Java EE 服务器/客户端架构,它们使用 SSL 连接相互通信。建立连接后,客户端可以询问服务器 Web 服务。我的问题是如何访问服务器 Web 服务中的客户端证书信息?我的服务器控制器如下:

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

@Path("mycontroller")
@Consumes(MediaType.APPLICATION_XML)
@Produces(MediaType.APPLICATION_XML)
public class Controller {

    @GET
    @Path("dosomething")
    public Response doSomething() {

        // How can I have access to certificate information here ?

        return Response.ok().build();

    }

}

【问题讨论】:

    标签: web-services jakarta-ee ssl jax-ws


    【解决方案1】:

    我找到了一种方法来做我想做的事。

    首先,必须将服务器配置为需要客户端证书身份验证。在我的情况下,我使用 JBoss 服务器,并且必须在standalone.xml 文件中添加它:

    ...
    <subsystem xmlns="urn:jboss:domain:web:1.1" default-virtual-server="default-host" native="false">
        ...
        <connector name="https" protocol="HTTP/1.1" scheme="https" socket-binding="https" enable-lookups="false" secure="true">
            <ssl name="localhost" key-alias="localhost" password="server" certificate-file="${jboss.server.config.dir}/server.jks" certificate-key-file="${jboss.server.config.dir}/server.jks" ca-certificate-file="${jboss.server.config.dir}/truststore.jks" protocol="TLSv1" verify-client="true" />
        </connector>
        ...
    </subsystem>
    ...
    

    然后我必须在我的控制器中注入 HttpServletRequest,最后我可以获得一个包含证书信息的 X509Certificate 实例:

    import javax.ws.rs.Consumes;
    import javax.ws.rs.GET;
    import javax.ws.rs.Path;
    import javax.ws.rs.Produces;
    import javax.ws.rs.core.MediaType;
    import javax.ws.rs.core.Response;
    import javax.servlet.http.HttpServletRequest;
    import java.security.cert.X509Certificate;
    
    @Path("mycontroller")
    @Consumes(MediaType.APPLICATION_XML)
    @Produces(MediaType.APPLICATION_XML)
    public class Controller {
    
        @Context 
        private HttpServletRequest request;
    
        @GET
        @Path("dosomething")
        public Response doSomething() {
    
            X509Certificate[] certChain = (X509Certificate[]) request.getAttribute("javax.servlet.request.X509Certificate");
            X509Certificate certificate = certChain[0];
    
            return Response.ok().build();
    
        }
    
    }
    

    【讨论】:

      【解决方案2】:

      如果您正在寻找可以在 HTTP 标头和 HTTP Servlet Reqeust 对象中找到的标准证书信息,例如来自 Apache HTTP 反向代理的客户端证书信息。你可以注入这些

      例如:

      @Context 私有 HttpServletRequest servletRequest; @Context private HttpServletContext servletContext;

      (见Get HttpServletRequest in Jax Rs / Appfuse application?Java EE tutorial

      如果您希望访问密钥库文件并加载证书的私钥,则应通过 JNDI 文件资源或 JCA 适配器完成文件访问。

      但我建议小心,应用程序服务器应该处理所有 SSL/TLS 连接安全,您的 WAR 组件只是声明它希望连接在 web.xml 文件中是“机密的”。将消息级别的安全性和身份验证与应用程序或传输协议安全性混合可以破坏关注点分离。即在总线或集线器场景中将身份验证附加到消息。

      【讨论】:

      • 感谢您的回复。我的客户正在使用包含“通用名称”的“鲍勃”的证书进行连接。我希望能够在我的控制器中说“Hello Bob”。我开始严重怀疑这是否可能。
      猜你喜欢
      • 1970-01-01
      • 2013-01-07
      • 2020-05-09
      • 1970-01-01
      • 1970-01-01
      • 2018-06-13
      • 1970-01-01
      • 1970-01-01
      • 2018-07-07
      相关资源
      最近更新 更多