Search code examples
web-servicesjakarta-eessljax-ws

How can I access to certificate information


I have a Java EE server/client architecture which communicate with each other by using SSL connection. When the connection is made, the client can interrogate the server web services. My question is how can I access to client certificate information in the server web service ? My server controller below :

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();

    }

}

Solution

  • I found a way to do what I wanted.

    First, the server has to be configurated to require client certificate authentication. In my case I use a JBoss server and had to add this in the standalone.xml file :

    ...
    <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>
    ...
    

    And then in my controller I had to inject HttpServletRequest and finally I could obtain an instance of X509Certificate which contains the certificate information :

    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();
    
        }
    
    }