1

I am creating a Vaadin web application that requires users to authenticate via login and password, I would like to know if it is possible to add CAC authentication as another mean of authentication.

In summary, my goal is to allow access to the website if the user is already authenticated with its CAC or require standard login (name/password) if the user is not CAC authenticated

By searching and googling around I have found Java PKCS#11, but it looks like it is a library for desktop integration.

Also I have seen this and this posts, that look similar to my situation but actually they are not. The first one talks about requirement of certification for the whole web application by configuring a web server. The second one presents Java PKCS#11 as desktop solution.

Again, what I wish to have is a "parallel" login, if the browser sends a CAC certificate to the server, the server should not require standard login, otherwise yes. Is it possible? Also, if the CAC certificate is sent to the server is there a way to retrieve data about this CAC, like owner's name?

Community
  • 1
  • 1
djeison
  • 490
  • 2
  • 5
  • 20

1 Answers1

2

In a correctly configured servlet container you can use this to read the client certificate (if any exists)

String cipherSuite = (String) req.getAttribute("javax.servlet.request.cipher_suite");

if (cipherSuite != null) {
    X509Certificate certChain[] = (X509Certificate[]) req.getAttribute("javax.servlet.request.X509Certificate");
    if (certChain != null) {
        for (int i = 0; i < certChain.length; i++) {
            System.out.println ("Client Certificate [" + i + "] = "
                    + certChain[i].toString());
        }
    }
}
André Schild
  • 4,592
  • 5
  • 28
  • 42
  • I tried this, but `cipherSuite` is always null. The CAC card I am using for this test is connected and is listed under my certificates. Should I configure Jetty first? – djeison Jul 23 '15 at 17:59
  • Does your jetty request a client certificate at all? If not, then there is no chance the client will send you one – André Schild Jul 23 '15 at 18:11
  • No, it doesn't. I have not configured SSL on my Jetty. Do you have any information on how to do that? – djeison Jul 23 '15 at 20:02
  • Is your jetty the one accepting the https connection, or doe you have a apache/nginx or other server in front of it? – André Schild Jul 23 '15 at 20:04
  • Jetty is the one which will accept the https connection. I have taken a look at http://www.eclipse.org/jetty/documentation/9.2.6.v20141205/configuring-ssl.html#loading-keys-and-certificates but I could not find out how to configure it to request CAC authentication. – djeison Jul 23 '15 at 20:06
  • Look here http://stackoverflow.com/questions/752890/how-to-connect-to-https-server-using-common-access-card and http://stackoverflow.com/questions/544056/common-access-card-cac-authentication-using-java these should solve your problem – André Schild Jul 23 '15 at 20:11
  • Ok, but that question is about implementing a Java client that connects to a HTTPS web application. I need to configure SSL in my web application so the client sends the certificate in the request, and then I can check if this request contains a CAC certificate. If so, the user don't need to use login/password to login in the web app. Does it make sense? – djeison Jul 24 '15 at 14:07
  • 1
    It is very easy to set up an embedded Jetty server that requests client authentication: One just needs to add the statement SslContextFactory.setNeedClientAuth(true); to the ssl context when configuring the server. Any client that has its certificate in the server's truststore will be able to establish a TLS connection to the server. But the weak point will be to have the correct keys in the truststore... – André Schild Jul 24 '15 at 14:16
  • Would you have an example on how to add `SslContextFactory.setNeedClientAuth(true);` to the ssl context? – djeison Jul 24 '15 at 14:36