Apache mod_ssl tomcate Axis https user authentication
package com.tiandao.ws.util;
import java.io.ByteArrayInputStream;
import java.security.Principal;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import org.apache.axis.MessageContext;
import org.apache.axis.transport.http.HTTPConstants;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
public class AxisUtil
{
/**
* This method read all possible certificate from request. If the apache
* passes certificate to tomcate in "SSL_CLIENT_CERT", this method will
* reads and create the certificate.
*
* @param request
* @return
*/
public static X509Certificate getX509Certificate(HttpServletRequest request)
{
X509Certificate ret = null;
String certString = null;
Object obj = request
.getAttribute("javax.servlet.request.X509Certificate");
if (obj != null)
{
if (obj instanceof String)
{
certString = (String) obj;
ret = stringToX509(certString);
} else if (obj instanceof X509Certificate[])
{
if (((X509Certificate[]) obj) != null
&& ((X509Certificate[]) obj).length > 0)
ret = ((X509Certificate[]) obj)[0];
}
} else
{
certString = (String) request.getAttribute("SSL_CLIENT_CERT");
ret = stringToX509(certString);
}
return ret;
}
/**
* A string of a PEM format certificate as input, will return a
* X509Certificate.
*
* @param cert
* @return
*/
public static X509Certificate stringToX509(String cert)
{
CertificateFactory cf;
try
{
cf = CertificateFactory.getInstance("X.509");
X509Certificate ret = null;
byte[] bytes = cert.getBytes();
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
ret = (X509Certificate) cf.generateCertificate(bais);
return ret;
} catch (CertificateException e)
{
e.printStackTrace();
return null;
}
}
public static Principal getUserPrincipal(MessageContext mctx)
{
HttpServletRequest req = (HttpServletRequest) mctx
.getProperty(HTTPConstants.MC_HTTP_SERVLETREQUEST);
X509Certificate[] certificate = (X509Certificate[]) req
.getAttribute("javax.servlet.request.X509Certificate");
Principal principal = certificate[0].getSubjectDN();
return principal;
}
public static WebApplicationContext getAppContext(MessageContext mctx)
{
HttpServlet servlet = (HttpServlet) mctx
.getProperty(HTTPConstants.MC_HTTP_SERVLET);
ServletContext servletContext = servlet.getServletContext();
WebApplicationContext webAppContext = WebApplicationContextUtils
.getRequiredWebApplicationContext(servletContext);
return webAppContext;
}
public static String getUserDN(MessageContext mctx)
{
Principal principal = getUserPrincipal(mctx);
return principal.getName();
}
}
Here are some explanation.
Apache was configured to pass the user certificate to tomcat. "javax.servlet.request.X509Certificate" and request attribute "SSL_CLIENT_CERT" will all be filled up with the proper certificate information.
Some wrapping method was in there for my own convenient.
import java.io.ByteArrayInputStream;
import java.security.Principal;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import org.apache.axis.MessageContext;
import org.apache.axis.transport.http.HTTPConstants;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
public class AxisUtil
{
/**
* This method read all possible certificate from request. If the apache
* passes certificate to tomcate in "SSL_CLIENT_CERT", this method will
* reads and create the certificate.
*
* @param request
* @return
*/
public static X509Certificate getX509Certificate(HttpServletRequest request)
{
X509Certificate ret = null;
String certString = null;
Object obj = request
.getAttribute("javax.servlet.request.X509Certificate");
if (obj != null)
{
if (obj instanceof String)
{
certString = (String) obj;
ret = stringToX509(certString);
} else if (obj instanceof X509Certificate[])
{
if (((X509Certificate[]) obj) != null
&& ((X509Certificate[]) obj).length > 0)
ret = ((X509Certificate[]) obj)[0];
}
} else
{
certString = (String) request.getAttribute("SSL_CLIENT_CERT");
ret = stringToX509(certString);
}
return ret;
}
/**
* A string of a PEM format certificate as input, will return a
* X509Certificate.
*
* @param cert
* @return
*/
public static X509Certificate stringToX509(String cert)
{
CertificateFactory cf;
try
{
cf = CertificateFactory.getInstance("X.509");
X509Certificate ret = null;
byte[] bytes = cert.getBytes();
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
ret = (X509Certificate) cf.generateCertificate(bais);
return ret;
} catch (CertificateException e)
{
e.printStackTrace();
return null;
}
}
public static Principal getUserPrincipal(MessageContext mctx)
{
HttpServletRequest req = (HttpServletRequest) mctx
.getProperty(HTTPConstants.MC_HTTP_SERVLETREQUEST);
X509Certificate[] certificate = (X509Certificate[]) req
.getAttribute("javax.servlet.request.X509Certificate");
Principal principal = certificate[0].getSubjectDN();
return principal;
}
public static WebApplicationContext getAppContext(MessageContext mctx)
{
HttpServlet servlet = (HttpServlet) mctx
.getProperty(HTTPConstants.MC_HTTP_SERVLET);
ServletContext servletContext = servlet.getServletContext();
WebApplicationContext webAppContext = WebApplicationContextUtils
.getRequiredWebApplicationContext(servletContext);
return webAppContext;
}
public static String getUserDN(MessageContext mctx)
{
Principal principal = getUserPrincipal(mctx);
return principal.getName();
}
}
Here are some explanation.
Apache was configured to pass the user certificate to tomcat. "javax.servlet.request.X509Certificate" and request attribute "SSL_CLIENT_CERT" will all be filled up with the proper certificate information.
Some wrapping method was in there for my own convenient.
Comments