adding mutual ssl support in clustered setup

4.x.x
inosh-perera 9 years ago
parent d9015b92a0
commit 67b210fe86

@ -288,6 +288,19 @@ public class CertificateGenerator {
return lookUpCertificate;
}
public CertificateResponse verifyCertificateDN(String distinguishedName) throws KeystoreException {
CertificateResponse lookUpCertificate = null;
KeyStoreReader keyStoreReader = new KeyStoreReader();
if (distinguishedName != null && !distinguishedName.isEmpty()) {
String[] dnSplits = distinguishedName.split("/CN=");
if (dnSplits != null) {
String commonNameExtracted = dnSplits[dnSplits.length-1];
lookUpCertificate = keyStoreReader.getCertificateBySerial(commonNameExtracted);
}
}
return lookUpCertificate;
}
public static String getCommonName(X509Certificate requestCertificate) {
String distinguishedName = requestCertificate.getSubjectDN().getName();
if(distinguishedName != null && !distinguishedName.isEmpty()) {

@ -56,6 +56,8 @@ public interface CertificateManagementService {
public CertificateResponse verifyPEMSignature(X509Certificate requestCertificate) throws KeystoreException;
public CertificateResponse verifySubjectDN(String requestDN) throws KeystoreException;
public X509Certificate extractCertificateFromSignature(String headerSignature) throws KeystoreException;
String extractChallengeToken(X509Certificate certificate);

@ -108,6 +108,10 @@ public class CertificateManagementServiceImpl implements CertificateManagementSe
return certificateGenerator.verifyPEMSignature(requestCertificate);
}
@Override public CertificateResponse verifySubjectDN(String requestDN) throws KeystoreException {
return certificateGenerator.verifyCertificateDN(requestDN);
}
public X509Certificate extractCertificateFromSignature(String headerSignature) throws KeystoreException {
return certificateGenerator.extractCertificateFromSignature(headerSignature);
}

@ -28,6 +28,7 @@ public class CertificateAuthenticator implements WebappAuthenticator {
private static final Log log = LogFactory.getLog(CertificateAuthenticator.class);
private static final String CERTIFICATE_AUTHENTICATOR = "CertificateAuth";
private static final String MUTUAL_AUTH_HEADER = "mutual-auth-header";
private static final String PROXY_MUTUAL_AUTH_HEADER = "proxy-mutual-auth-header";
private static final String CERTIFICATE_VERIFICATION_HEADER = "certificate-verification-header";
private static final String CLIENT_CERTIFICATE_ATTRIBUTE = "javax.servlet.request.X509Certificate";
@ -38,8 +39,8 @@ public class CertificateAuthenticator implements WebappAuthenticator {
@Override
public boolean canHandle(Request request) {
if (request.getHeader(CERTIFICATE_VERIFICATION_HEADER) != null || request.getHeader(MUTUAL_AUTH_HEADER) !=
null) {
if (request.getHeader(CERTIFICATE_VERIFICATION_HEADER) != null || request.getHeader(MUTUAL_AUTH_HEADER) != null
|| request.getHeader(PROXY_MUTUAL_AUTH_HEADER) != null) {
return true;
}
return false;
@ -56,35 +57,20 @@ public class CertificateAuthenticator implements WebappAuthenticator {
String certVerificationHeader = request.getContext().findParameter(CERTIFICATE_VERIFICATION_HEADER);
try {
if (request.getHeader(MUTUAL_AUTH_HEADER) != null) {
// When there is a load balancer terminating mutual SSL, it should pass this header along and
// as the value of this header, the client certificate subject dn should be passed.
if (request.getHeader(PROXY_MUTUAL_AUTH_HEADER) != null) {
CertificateResponse certificateResponse = AuthenticatorFrameworkDataHolder.getInstance().
getCertificateManagementService().verifySubjectDN(request.getHeader(PROXY_MUTUAL_AUTH_HEADER));
authenticationInfo = checkCertificateResponse(certificateResponse);
}
else if (request.getHeader(MUTUAL_AUTH_HEADER) != null) {
X509Certificate[] clientCertificate = (X509Certificate[]) request.
getAttribute(CLIENT_CERTIFICATE_ATTRIBUTE);
if (clientCertificate != null && clientCertificate[0] != null) {
CertificateResponse certificateResponse = AuthenticatorFrameworkDataHolder.getInstance().
getCertificateManagementService().verifyPEMSignature(clientCertificate[0]);
if (certificateResponse == null) {
authenticationInfo.setStatus(Status.FAILURE);
authenticationInfo.setMessage("Certificate sent doesn't match any certificate in the store." +
" Unauthorized access attempt.");
} else if (certificateResponse.getCommonName() != null && !certificateResponse.getCommonName().
isEmpty()) {
authenticationInfo.setTenantId(certificateResponse.getTenantId());
authenticationInfo.setStatus(Status.CONTINUE);
authenticationInfo.setUsername(certificateResponse.getCommonName());
try {
authenticationInfo.setTenantDomain(Utils.
getTenantDomain(
certificateResponse.getTenantId()));
} catch (AuthenticationException e) {
authenticationInfo.setStatus(Status.FAILURE);
authenticationInfo.setMessage("Could not identify tenant domain.");
}
} else {
authenticationInfo.setStatus(Status.FAILURE);
authenticationInfo.setMessage("A matching certificate is found, " +
"but the serial number is missing in the database.");
}
authenticationInfo = checkCertificateResponse(certificateResponse);
} else {
authenticationInfo.setStatus(Status.FAILURE);
@ -133,6 +119,33 @@ public class CertificateAuthenticator implements WebappAuthenticator {
return authenticationInfo;
}
private AuthenticationInfo checkCertificateResponse(CertificateResponse certificateResponse) {
AuthenticationInfo authenticationInfo = new AuthenticationInfo();
if (certificateResponse == null) {
authenticationInfo.setStatus(Status.FAILURE);
authenticationInfo.setMessage("Certificate sent doesn't match any certificate in the store." +
" Unauthorized access attempt.");
} else if (certificateResponse.getCommonName() != null && !certificateResponse.getCommonName().
isEmpty()) {
authenticationInfo.setTenantId(certificateResponse.getTenantId());
authenticationInfo.setStatus(Status.CONTINUE);
authenticationInfo.setUsername(certificateResponse.getCommonName());
try {
authenticationInfo.setTenantDomain(Utils.
getTenantDomain(
certificateResponse.getTenantId()));
} catch (AuthenticationException e) {
authenticationInfo.setStatus(Status.FAILURE);
authenticationInfo.setMessage("Could not identify tenant domain.");
}
} else {
authenticationInfo.setStatus(Status.FAILURE);
authenticationInfo.setMessage("A matching certificate is found, " +
"but the serial number is missing in the database.");
}
return authenticationInfo;
}
@Override
public String getName() {
return CERTIFICATE_AUTHENTICATOR;

Loading…
Cancel
Save