This is an automated email from the ASF dual-hosted git repository. lmccay pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/knox.git
The following commit(s) were added to refs/heads/master by this push: new ed77c70 KNOX-2401 - Extend ClientCert Authentication Provider for CN as PrimaryPrincipal (#384) ed77c70 is described below commit ed77c70a76f351744d7b62b1ef9cacd753ef0ae6 Author: lmccay <lmc...@apache.org> AuthorDate: Sun Nov 15 18:56:11 2020 -0500 KNOX-2401 - Extend ClientCert Authentication Provider for CN as PrimaryPrincipal (#384) Change-Id: I416ae92a0f01f032e4d0ac9bb5e6bf03ce35267c --- gateway-provider-security-clientcert/pom.xml | 4 +++ .../clientcert/filter/ClientCertFilter.java | 36 ++++++++++++++++++++-- .../clientcert/filter/ClientCertMessages.java | 28 +++++++++++++++++ 3 files changed, 66 insertions(+), 2 deletions(-) diff --git a/gateway-provider-security-clientcert/pom.xml b/gateway-provider-security-clientcert/pom.xml index 6a32ed1..fe09c7c 100755 --- a/gateway-provider-security-clientcert/pom.xml +++ b/gateway-provider-security-clientcert/pom.xml @@ -31,6 +31,10 @@ <dependencies> <dependency> <groupId>org.apache.knox</groupId> + <artifactId>gateway-i18n</artifactId> + </dependency> + <dependency> + <groupId>org.apache.knox</groupId> <artifactId>gateway-spi</artifactId> </dependency> <dependency> diff --git a/gateway-provider-security-clientcert/src/main/java/org/apache/knox/gateway/clientcert/filter/ClientCertFilter.java b/gateway-provider-security-clientcert/src/main/java/org/apache/knox/gateway/clientcert/filter/ClientCertFilter.java index a7f967a..95de828 100755 --- a/gateway-provider-security-clientcert/src/main/java/org/apache/knox/gateway/clientcert/filter/ClientCertFilter.java +++ b/gateway-provider-security-clientcert/src/main/java/org/apache/knox/gateway/clientcert/filter/ClientCertFilter.java @@ -25,7 +25,9 @@ import org.apache.knox.gateway.audit.api.Auditor; import org.apache.knox.gateway.audit.api.ResourceType; import org.apache.knox.gateway.audit.log4j.audit.AuditConstants; import org.apache.knox.gateway.filter.AbstractGatewayFilter; +import org.apache.knox.gateway.i18n.messages.MessagesFactory; import org.apache.knox.gateway.security.PrimaryPrincipal; +import org.apache.knox.gateway.util.X500PrincipalParser; import java.io.IOException; import java.security.PrivilegedActionException; @@ -33,6 +35,7 @@ import java.security.PrivilegedExceptionAction; import java.security.cert.X509Certificate; import javax.security.auth.Subject; +import javax.security.auth.x500.X500Principal; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; @@ -43,14 +46,25 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ClientCertFilter implements Filter { + private static ClientCertMessages log = MessagesFactory.get( ClientCertMessages.class ); + private static final String CLIENT_CERT_PRINCIPAL_ATTRIBUTE_NAME = "client.cert.principal.attribute.name"; private static AuditService auditService = AuditServiceFactory.getAuditService(); private static Auditor auditor = auditService.getAuditor( AuditConstants.DEFAULT_AUDITOR_NAME, AuditConstants.KNOX_SERVICE_NAME, AuditConstants.KNOX_COMPONENT_NAME ); + private String principalAttributeName; @Override public void init(FilterConfig filterConfig) { - + principalAttributeName = filterConfig.getInitParameter(CLIENT_CERT_PRINCIPAL_ATTRIBUTE_NAME); + if (principalAttributeName == null) { + principalAttributeName = "DN"; + } + else if (!"DN".equalsIgnoreCase(principalAttributeName) && + !"CN".equalsIgnoreCase(principalAttributeName)) { + log.unknownCertificateAttribute(principalAttributeName); + principalAttributeName = "DN"; + } } @Override @@ -58,7 +72,7 @@ public class ClientCertFilter implements Filter { HttpServletRequest httpRequest = (HttpServletRequest)request; X509Certificate cert = extractCertificate(httpRequest); if (cert != null) { - String principal = cert.getSubjectDN().getName(); + String principal = extractPrincipalFromCert(cert); Subject subject = new Subject(); subject.getPrincipals().add(new PrimaryPrincipal(principal)); @@ -71,6 +85,24 @@ public class ClientCertFilter implements Filter { } } + private String extractPrincipalFromCert(X509Certificate cert) { + String p = null; + if ("DN".equalsIgnoreCase(principalAttributeName)) { + p = cert.getSubjectDN().getName(); + } + else if ("CN".equalsIgnoreCase(principalAttributeName)) { + X500Principal x500Principal = cert.getSubjectX500Principal(); + X500PrincipalParser parser = new X500PrincipalParser(x500Principal); + p = parser.getCN(); + } + else { + log.unknownCertificateAttribute(principalAttributeName); + p = cert.getSubjectDN().getName(); + } + + return p; + } + private X509Certificate extractCertificate(HttpServletRequest req) { X509Certificate[] certs = (X509Certificate[]) req.getAttribute("javax.servlet.request.X509Certificate"); if (null != certs && certs.length > 0) { diff --git a/gateway-provider-security-clientcert/src/main/java/org/apache/knox/gateway/clientcert/filter/ClientCertMessages.java b/gateway-provider-security-clientcert/src/main/java/org/apache/knox/gateway/clientcert/filter/ClientCertMessages.java new file mode 100644 index 0000000..84f9dd5 --- /dev/null +++ b/gateway-provider-security-clientcert/src/main/java/org/apache/knox/gateway/clientcert/filter/ClientCertMessages.java @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.knox.gateway.clientcert.filter; + +import org.apache.knox.gateway.i18n.messages.Message; +import org.apache.knox.gateway.i18n.messages.MessageLevel; +import org.apache.knox.gateway.i18n.messages.Messages; + +@Messages(logger="org.apache.knox.gateway") +public interface ClientCertMessages { + @Message( level = MessageLevel.ERROR, text = "Configured certificate attribute unknown - falling back to DN as principal: {0}" ) + void unknownCertificateAttribute(String attrName); +}