This is an automated email from the ASF dual-hosted git repository.
chriss pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi.git
The following commit(s) were added to refs/heads/main by this push:
new f0593a0034 NIFI-12272 Added Formatter for Certificate Distinguished
Names
f0593a0034 is described below
commit f0593a00344a8a1cd59e3dd46a08ac0fb958df2e
Author: exceptionfactory <[email protected]>
AuthorDate: Wed Oct 25 09:47:22 2023 -0500
NIFI-12272 Added Formatter for Certificate Distinguished Names
- Added standard implementation for formatting Subject and Issuer using RFC
1779
- Replaced direct method references to maintain compatibility with
historical getSubjectDN and getIssuerDN methods
This closes #7931
Signed-off-by: Chris Sampson <[email protected]>
---
minifi/minifi-c2/minifi-c2-service/pom.xml | 5 ++
.../authentication/X509AuthenticationToken.java | 4 +-
.../nifi/security/cert/PrincipalFormatter.java | 26 +++++---
.../security/cert/StandardPrincipalFormatter.java | 69 ++++++++++++++++++++++
.../cert/StandardPrincipalFormatterTest.java | 65 ++++++++++++++++++++
nifi-commons/nifi-site-to-site-client/pom.xml | 5 ++
.../socket/StandardSocketPeerIdentityProvider.java | 6 +-
.../nifi/remote/util/SiteToSiteRestApiClient.java | 3 +-
.../StandardSocketPeerIdentityProviderTest.java | 2 +-
.../nifi-email-processors/pom.xml | 5 ++
.../nifi/processors/email/smtp/SmtpConsumer.java | 3 +-
.../nifi-framework/nifi-site-to-site/pom.xml | 5 ++
.../nifi/remote/SocketRemoteSiteListener.java | 5 +-
.../nifi-web/nifi-web-security/pom.xml | 5 ++
.../x509/SubjectDnX509PrincipalExtractor.java | 7 ++-
.../x509/X509AuthenticationProviderTest.java | 2 +-
.../nifi/processors/standard/ListenTCPRecord.java | 7 ++-
...leHttpRequestCertificateAttributesProvider.java | 7 ++-
.../servlets/ContentAcknowledgmentServlet.java | 5 +-
.../standard/servlets/ListenHTTPServlet.java | 7 ++-
...tpRequestCertificateAttributesProviderTest.java | 12 ++--
.../nifi-registry-web-api/pom.xml | 5 ++
.../x509/SubjectDnX509PrincipalExtractor.java | 6 +-
23 files changed, 228 insertions(+), 38 deletions(-)
diff --git a/minifi/minifi-c2/minifi-c2-service/pom.xml
b/minifi/minifi-c2/minifi-c2-service/pom.xml
index f2c8123453..e4bfef4b2f 100644
--- a/minifi/minifi-c2/minifi-c2-service/pom.xml
+++ b/minifi/minifi-c2/minifi-c2-service/pom.xml
@@ -37,6 +37,11 @@ limitations under the License.
<artifactId>c2-protocol-api</artifactId>
<version>2.0.0-SNAPSHOT</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.nifi</groupId>
+ <artifactId>nifi-security-cert</artifactId>
+ <version>2.0.0-SNAPSHOT</version>
+ </dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
diff --git
a/minifi/minifi-c2/minifi-c2-service/src/main/java/org/apache/nifi/minifi/c2/security/authentication/X509AuthenticationToken.java
b/minifi/minifi-c2/minifi-c2-service/src/main/java/org/apache/nifi/minifi/c2/security/authentication/X509AuthenticationToken.java
index 50afcc2993..296637dce6 100644
---
a/minifi/minifi-c2/minifi-c2-service/src/main/java/org/apache/nifi/minifi/c2/security/authentication/X509AuthenticationToken.java
+++
b/minifi/minifi-c2/minifi-c2-service/src/main/java/org/apache/nifi/minifi/c2/security/authentication/X509AuthenticationToken.java
@@ -20,6 +20,8 @@ package org.apache.nifi.minifi.c2.security.authentication;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.Collection;
+
+import org.apache.nifi.security.cert.StandardPrincipalFormatter;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
@@ -36,7 +38,7 @@ public class X509AuthenticationToken extends
AbstractAuthenticationToken {
super(grantedAuthorities);
this.x509Certificates = Arrays.copyOf(x509Certificates,
x509Certificates.length, X509Certificate[].class);
X509Certificate x509Certificate = x509Certificates[0];
- this.subjectDn =
x509Certificate.getSubjectX500Principal().getName().trim();
+ this.subjectDn =
StandardPrincipalFormatter.getInstance().getSubject(x509Certificate);
}
@Override
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/SubjectDnX509PrincipalExtractor.java
b/nifi-commons/nifi-security-cert/src/main/java/org/apache/nifi/security/cert/PrincipalFormatter.java
similarity index 53%
copy from
nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/SubjectDnX509PrincipalExtractor.java
copy to
nifi-commons/nifi-security-cert/src/main/java/org/apache/nifi/security/cert/PrincipalFormatter.java
index c9992401c3..6cba7e40ec 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/SubjectDnX509PrincipalExtractor.java
+++
b/nifi-commons/nifi-security-cert/src/main/java/org/apache/nifi/security/cert/PrincipalFormatter.java
@@ -14,19 +14,27 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.nifi.web.security.x509;
+package org.apache.nifi.security.cert;
import java.security.cert.X509Certificate;
-import
org.springframework.security.web.authentication.preauth.x509.X509PrincipalExtractor;
/**
- * Principal extractor for extracting a DN.
+ * Abstraction for retrieving and formatting X.509 Certificate Subject and
Issuer Principal Distinguished Names
*/
-public class SubjectDnX509PrincipalExtractor implements X509PrincipalExtractor
{
-
- @Override
- public Object extractPrincipal(X509Certificate cert) {
- return cert.getSubjectX500Principal().getName().trim();
- }
+public interface PrincipalFormatter {
+ /**
+ * Get Subject Distinguished Name formatted as a string according to
standard implementation conventions
+ *
+ * @param certificate X.509 Certificate
+ * @return Formatted Subject Distinguished Name
+ */
+ String getSubject(X509Certificate certificate);
+ /**
+ * Get Issuer Distinguished Name formatted as a string according to
standard implementation conventions
+ *
+ * @param certificate X.509 Certificate
+ * @return Formatted Issuer Distinguished Name
+ */
+ String getIssuer(X509Certificate certificate);
}
diff --git
a/nifi-commons/nifi-security-cert/src/main/java/org/apache/nifi/security/cert/StandardPrincipalFormatter.java
b/nifi-commons/nifi-security-cert/src/main/java/org/apache/nifi/security/cert/StandardPrincipalFormatter.java
new file mode 100644
index 0000000000..be1bdbec7a
--- /dev/null
+++
b/nifi-commons/nifi-security-cert/src/main/java/org/apache/nifi/security/cert/StandardPrincipalFormatter.java
@@ -0,0 +1,69 @@
+/*
+ * 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.nifi.security.cert;
+
+import javax.security.auth.x500.X500Principal;
+import java.security.cert.X509Certificate;
+import java.util.Objects;
+
+/**
+ * Standard Principal Formatter implementation returns Subject and Issuer
formatted according to RFC 1779 following the convention of getSubjectDN and
getIssuerDN methods
+ */
+public class StandardPrincipalFormatter implements PrincipalFormatter {
+ private static final PrincipalFormatter INSTANCE = new
StandardPrincipalFormatter();
+
+ private StandardPrincipalFormatter() {
+
+ }
+
+ /**
+ * Get singleton instance of Principal Formatter
+ *
+ * @return Standard Principal Formatter
+ */
+ public static PrincipalFormatter getInstance() {
+ return INSTANCE;
+ }
+
+ /**
+ * Get Subject Distinguished Name formatted as a string according to RFC
1779 with spaces between elements
+ *
+ * @param certificate X.509 Certificate
+ * @return Subject Distinguished Name formatted according to RFC 1779
+ */
+ @Override
+ public String getSubject(final X509Certificate certificate) {
+ Objects.requireNonNull(certificate, "Certificate required");
+ return getFormatted(certificate.getSubjectX500Principal());
+ }
+
+ /**
+ * Get Issuer Distinguished Name formatted as a string according to RFC
1779 with spaces between elements
+ *
+ * @param certificate X.509 Certificate
+ * @return Issuer Distinguished Name formatted according to RFC 1779
+ */
+ @Override
+ public String getIssuer(final X509Certificate certificate) {
+ Objects.requireNonNull(certificate, "Certificate required");
+ return getFormatted(certificate.getIssuerX500Principal());
+ }
+
+ private String getFormatted(final X500Principal principal) {
+ return principal.getName(X500Principal.RFC1779);
+ }
+}
diff --git
a/nifi-commons/nifi-security-cert/src/test/java/org/apache/nifi/security/cert/StandardPrincipalFormatterTest.java
b/nifi-commons/nifi-security-cert/src/test/java/org/apache/nifi/security/cert/StandardPrincipalFormatterTest.java
new file mode 100644
index 0000000000..5cb21a28c7
--- /dev/null
+++
b/nifi-commons/nifi-security-cert/src/test/java/org/apache/nifi/security/cert/StandardPrincipalFormatterTest.java
@@ -0,0 +1,65 @@
+/*
+ * 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.nifi.security.cert;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import javax.security.auth.x500.X500Principal;
+import java.security.cert.X509Certificate;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.Mockito.when;
+
+@ExtendWith(MockitoExtension.class)
+class StandardPrincipalFormatterTest {
+
+ private static final String SUBJECT_CANONICAL =
"CN=Subject,O=Organization,C=US";
+
+ private static final String SUBJECT_FORMATTED = "CN=Subject,
O=Organization, C=US";
+
+ private static final X500Principal SUBJECT_PRINCIPAL = new
X500Principal(SUBJECT_CANONICAL);
+
+ private static final String ISSUER_CANONICAL = "CN=Certificate
Authority,O=Organization,C=US";
+
+ private static final String ISSUER_FORMATTED = "CN=Certificate Authority,
O=Organization, C=US";
+
+ private static final X500Principal ISSUER_PRINCIPAL = new
X500Principal(ISSUER_CANONICAL);
+
+ @Mock
+ private X509Certificate certificate;
+
+ @Test
+ void testGetSubject() {
+
when(certificate.getSubjectX500Principal()).thenReturn(SUBJECT_PRINCIPAL);
+
+ final String subject =
StandardPrincipalFormatter.getInstance().getSubject(certificate);
+
+ assertEquals(SUBJECT_FORMATTED, subject);
+ }
+
+ @Test
+ void testGetIssuer() {
+
when(certificate.getIssuerX500Principal()).thenReturn(ISSUER_PRINCIPAL);
+
+ final String issuer =
StandardPrincipalFormatter.getInstance().getIssuer(certificate);
+
+ assertEquals(ISSUER_FORMATTED, issuer);
+ }
+}
diff --git a/nifi-commons/nifi-site-to-site-client/pom.xml
b/nifi-commons/nifi-site-to-site-client/pom.xml
index 3f5ff4f261..8240b63ea1 100644
--- a/nifi-commons/nifi-site-to-site-client/pom.xml
+++ b/nifi-commons/nifi-site-to-site-client/pom.xml
@@ -47,6 +47,11 @@
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-security-ssl</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.apache.nifi</groupId>
+ <artifactId>nifi-security-cert</artifactId>
+ <version>2.0.0-SNAPSHOT</version>
+ </dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-xml-processing</artifactId>
diff --git
a/nifi-commons/nifi-site-to-site-client/src/main/java/org/apache/nifi/remote/client/socket/StandardSocketPeerIdentityProvider.java
b/nifi-commons/nifi-site-to-site-client/src/main/java/org/apache/nifi/remote/client/socket/StandardSocketPeerIdentityProvider.java
index c9bb973737..7619dd5c79 100644
---
a/nifi-commons/nifi-site-to-site-client/src/main/java/org/apache/nifi/remote/client/socket/StandardSocketPeerIdentityProvider.java
+++
b/nifi-commons/nifi-site-to-site-client/src/main/java/org/apache/nifi/remote/client/socket/StandardSocketPeerIdentityProvider.java
@@ -17,13 +17,14 @@
package org.apache.nifi.remote.client.socket;
import java.net.Socket;
-import java.security.Principal;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.Optional;
import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
+
+import org.apache.nifi.security.cert.StandardPrincipalFormatter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -60,8 +61,7 @@ public class StandardSocketPeerIdentityProvider implements
SocketPeerIdentityPro
logger.warn("Peer Identity not found: Peer Certificates not
provided [{}:{}]", peerHost, peerPort);
} else {
final X509Certificate peerCertificate = (X509Certificate)
peerCertificates[0];
- final Principal subjectDistinguishedName =
peerCertificate.getSubjectX500Principal();
- peerIdentity = subjectDistinguishedName.getName();
+ peerIdentity =
StandardPrincipalFormatter.getInstance().getSubject(peerCertificate);
}
} catch (final SSLPeerUnverifiedException e) {
logger.warn("Peer Identity not found: Peer Unverified [{}:{}]",
peerHost, peerPort);
diff --git
a/nifi-commons/nifi-site-to-site-client/src/main/java/org/apache/nifi/remote/util/SiteToSiteRestApiClient.java
b/nifi-commons/nifi-site-to-site-client/src/main/java/org/apache/nifi/remote/util/SiteToSiteRestApiClient.java
index dfa12840c9..b5ae8997c3 100644
---
a/nifi-commons/nifi-site-to-site-client/src/main/java/org/apache/nifi/remote/util/SiteToSiteRestApiClient.java
+++
b/nifi-commons/nifi-site-to-site-client/src/main/java/org/apache/nifi/remote/util/SiteToSiteRestApiClient.java
@@ -116,6 +116,7 @@ import org.apache.nifi.remote.protocol.ResponseCode;
import org.apache.nifi.remote.protocol.http.HttpHeaders;
import org.apache.nifi.remote.protocol.http.HttpProxy;
import org.apache.nifi.reporting.Severity;
+import org.apache.nifi.security.cert.StandardPrincipalFormatter;
import org.apache.nifi.stream.io.StreamUtils;
import org.apache.nifi.web.api.dto.ControllerDTO;
import org.apache.nifi.web.api.dto.remote.PeerDTO;
@@ -317,7 +318,7 @@ public class SiteToSiteRestApiClient implements Closeable {
try {
final X509Certificate cert = (X509Certificate)
certChain[0];
- trustedPeerDn =
cert.getSubjectX500Principal().getName().trim();
+ trustedPeerDn =
StandardPrincipalFormatter.getInstance().getSubject(cert);
} catch (final RuntimeException e) {
final String msg = "Could not extract subject DN from SSL
session peer certificate";
logger.warn(msg);
diff --git
a/nifi-commons/nifi-site-to-site-client/src/test/java/org/apache/nifi/remote/client/socket/StandardSocketPeerIdentityProviderTest.java
b/nifi-commons/nifi-site-to-site-client/src/test/java/org/apache/nifi/remote/client/socket/StandardSocketPeerIdentityProviderTest.java
index a02d063363..2fb3bf120b 100644
---
a/nifi-commons/nifi-site-to-site-client/src/test/java/org/apache/nifi/remote/client/socket/StandardSocketPeerIdentityProviderTest.java
+++
b/nifi-commons/nifi-site-to-site-client/src/test/java/org/apache/nifi/remote/client/socket/StandardSocketPeerIdentityProviderTest.java
@@ -38,7 +38,7 @@ import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class StandardSocketPeerIdentityProviderTest {
- private static final String DISTINGUISHED_NAME = "CN=Common
Name,OU=Organizational Unit,O=Organization";
+ private static final String DISTINGUISHED_NAME = "CN=Common Name,
OU=Organizational Unit, O=Organization";
@Mock
SSLSocket sslSocket;
diff --git a/nifi-nar-bundles/nifi-email-bundle/nifi-email-processors/pom.xml
b/nifi-nar-bundles/nifi-email-bundle/nifi-email-processors/pom.xml
index 9ba5299b1d..a8c050446e 100644
--- a/nifi-nar-bundles/nifi-email-bundle/nifi-email-processors/pom.xml
+++ b/nifi-nar-bundles/nifi-email-bundle/nifi-email-processors/pom.xml
@@ -39,6 +39,11 @@
<artifactId>nifi-utils</artifactId>
<version>2.0.0-SNAPSHOT</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.nifi</groupId>
+ <artifactId>nifi-security-cert</artifactId>
+ <version>2.0.0-SNAPSHOT</version>
+ </dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-oauth2-provider-api</artifactId>
diff --git
a/nifi-nar-bundles/nifi-email-bundle/nifi-email-processors/src/main/java/org/apache/nifi/processors/email/smtp/SmtpConsumer.java
b/nifi-nar-bundles/nifi-email-bundle/nifi-email-processors/src/main/java/org/apache/nifi/processors/email/smtp/SmtpConsumer.java
index 765533a319..d025352920 100644
---
a/nifi-nar-bundles/nifi-email-bundle/nifi-email-processors/src/main/java/org/apache/nifi/processors/email/smtp/SmtpConsumer.java
+++
b/nifi-nar-bundles/nifi-email-bundle/nifi-email-processors/src/main/java/org/apache/nifi/processors/email/smtp/SmtpConsumer.java
@@ -38,6 +38,7 @@ import org.apache.nifi.processor.ProcessSession;
import org.apache.nifi.processor.ProcessSessionFactory;
import org.apache.nifi.processor.exception.FlowFileAccessException;
import org.apache.nifi.processors.email.ListenSMTP;
+import org.apache.nifi.security.cert.StandardPrincipalFormatter;
import org.apache.nifi.stream.io.LimitingInputStream;
import org.apache.nifi.util.StopWatch;
import org.subethamail.smtp.MessageContext;
@@ -141,7 +142,7 @@ public class SmtpConsumer implements MessageHandler {
for (int i = 0; i < tlsPeerCertificates.length; i++) {
if (tlsPeerCertificates[i] instanceof final X509Certificate
x509Cert) {
attributes.put("smtp.certificate." + i + ".serial",
x509Cert.getSerialNumber().toString());
- attributes.put("smtp.certificate." + i + ".subjectName",
x509Cert.getSubjectX500Principal().getName());
+ attributes.put("smtp.certificate." + i + ".subjectName",
StandardPrincipalFormatter.getInstance().getSubject(x509Cert));
}
}
}
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-site-to-site/pom.xml
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-site-to-site/pom.xml
index d46b9e73ba..28baddf429 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-site-to-site/pom.xml
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-site-to-site/pom.xml
@@ -51,6 +51,11 @@
<artifactId>nifi-security-identity</artifactId>
<version>2.0.0-SNAPSHOT</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.nifi</groupId>
+ <artifactId>nifi-security-cert</artifactId>
+ <version>2.0.0-SNAPSHOT</version>
+ </dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-mock</artifactId>
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-site-to-site/src/main/java/org/apache/nifi/remote/SocketRemoteSiteListener.java
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-site-to-site/src/main/java/org/apache/nifi/remote/SocketRemoteSiteListener.java
index 5f9f1c0f46..f3c5616f62 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-site-to-site/src/main/java/org/apache/nifi/remote/SocketRemoteSiteListener.java
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-site-to-site/src/main/java/org/apache/nifi/remote/SocketRemoteSiteListener.java
@@ -27,7 +27,6 @@ import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.security.GeneralSecurityException;
-import java.security.Principal;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
@@ -54,6 +53,7 @@ import
org.apache.nifi.remote.io.socket.SocketCommunicationsSession;
import org.apache.nifi.remote.protocol.CommunicationsSession;
import org.apache.nifi.remote.protocol.RequestType;
import org.apache.nifi.remote.protocol.ServerProtocol;
+import org.apache.nifi.security.cert.StandardPrincipalFormatter;
import org.apache.nifi.security.util.TlsPlatform;
import org.apache.nifi.util.NiFiProperties;
import org.slf4j.Logger;
@@ -350,8 +350,7 @@ public class SocketRemoteSiteListener implements
RemoteSiteListener {
}
final X509Certificate peerCertificate = (X509Certificate)
peerCertificates[0];
- final Principal subjectDistinguishedName =
peerCertificate.getSubjectX500Principal();
- return subjectDistinguishedName.getName();
+ return
StandardPrincipalFormatter.getInstance().getSubject(peerCertificate);
}
private boolean handleTlsError(String msg) {
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/pom.xml
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/pom.xml
index f7615ab6c4..c2620d13dd 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/pom.xml
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/pom.xml
@@ -106,6 +106,11 @@
<artifactId>nifi-security-identity</artifactId>
<version>2.0.0-SNAPSHOT</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.nifi</groupId>
+ <artifactId>nifi-security-cert</artifactId>
+ <version>2.0.0-SNAPSHOT</version>
+ </dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-framework-core</artifactId>
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/SubjectDnX509PrincipalExtractor.java
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/SubjectDnX509PrincipalExtractor.java
index c9992401c3..2ef3f4a36f 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/SubjectDnX509PrincipalExtractor.java
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/SubjectDnX509PrincipalExtractor.java
@@ -17,6 +17,8 @@
package org.apache.nifi.web.security.x509;
import java.security.cert.X509Certificate;
+
+import org.apache.nifi.security.cert.StandardPrincipalFormatter;
import
org.springframework.security.web.authentication.preauth.x509.X509PrincipalExtractor;
/**
@@ -25,8 +27,7 @@ import
org.springframework.security.web.authentication.preauth.x509.X509Principa
public class SubjectDnX509PrincipalExtractor implements X509PrincipalExtractor
{
@Override
- public Object extractPrincipal(X509Certificate cert) {
- return cert.getSubjectX500Principal().getName().trim();
+ public Object extractPrincipal(final X509Certificate cert) {
+ return StandardPrincipalFormatter.getInstance().getSubject(cert);
}
-
}
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/x509/X509AuthenticationProviderTest.java
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/x509/X509AuthenticationProviderTest.java
index 7d651147ed..38439fefdf 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/x509/X509AuthenticationProviderTest.java
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/x509/X509AuthenticationProviderTest.java
@@ -277,7 +277,7 @@ public class X509AuthenticationProviderTest {
final X509Certificate certificate = mock(X509Certificate.class);
when(certificate.getSubjectX500Principal()).then(invocation -> {
final X500Principal principal = mock(X500Principal.class);
- when(principal.getName()).thenReturn(identity);
+ when(principal.getName(any())).thenReturn(identity);
return principal;
});
return certificate;
diff --git
a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/ListenTCPRecord.java
b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/ListenTCPRecord.java
index 06876570c8..8708e0e6f0 100644
---
a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/ListenTCPRecord.java
+++
b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/ListenTCPRecord.java
@@ -67,6 +67,8 @@ import
org.apache.nifi.processor.util.listen.ListenerProperties;
import org.apache.nifi.record.listen.SSLSocketChannelRecordReader;
import org.apache.nifi.record.listen.SocketChannelRecordReader;
import org.apache.nifi.record.listen.SocketChannelRecordReaderDispatcher;
+import org.apache.nifi.security.cert.PrincipalFormatter;
+import org.apache.nifi.security.cert.StandardPrincipalFormatter;
import org.apache.nifi.security.util.ClientAuth;
import org.apache.nifi.serialization.RecordReader;
import org.apache.nifi.serialization.RecordReaderFactory;
@@ -486,8 +488,9 @@ public class ListenTCPRecord extends AbstractProcessor {
final Certificate[] certificates =
sslSession.getPeerCertificates();
if (certificates.length > 0) {
final X509Certificate certificate = (X509Certificate)
certificates[0];
- attributes.put(CLIENT_CERTIFICATE_SUBJECT_DN_ATTRIBUTE,
certificate.getSubjectX500Principal().toString());
- attributes.put(CLIENT_CERTIFICATE_ISSUER_DN_ATTRIBUTE,
certificate.getIssuerX500Principal().toString());
+ final PrincipalFormatter principalFormatter =
StandardPrincipalFormatter.getInstance();
+ attributes.put(CLIENT_CERTIFICATE_SUBJECT_DN_ATTRIBUTE,
principalFormatter.getSubject(certificate));
+ attributes.put(CLIENT_CERTIFICATE_ISSUER_DN_ATTRIBUTE,
principalFormatter.getIssuer(certificate));
}
} catch (final SSLPeerUnverifiedException peerUnverifiedException)
{
getLogger().debug("Remote Peer [{}] not verified: client
certificates not provided",
diff --git
a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/http/HandleHttpRequestCertificateAttributesProvider.java
b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/http/HandleHttpRequestCertificateAttributesProvider.java
index 814fea3f81..03e6c29264 100644
---
a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/http/HandleHttpRequestCertificateAttributesProvider.java
+++
b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/http/HandleHttpRequestCertificateAttributesProvider.java
@@ -17,7 +17,9 @@
package org.apache.nifi.processors.standard.http;
import org.apache.nifi.security.cert.CertificateAttributeReader;
+import org.apache.nifi.security.cert.PrincipalFormatter;
import org.apache.nifi.security.cert.StandardCertificateAttributeReader;
+import org.apache.nifi.security.cert.StandardPrincipalFormatter;
import org.apache.nifi.security.cert.SubjectAlternativeName;
import javax.servlet.http.HttpServletRequest;
@@ -65,8 +67,9 @@ public class HandleHttpRequestCertificateAttributesProvider
implements Certifica
private Map<String, String> getCertificateAttributes(final X509Certificate
certificate) {
final Map<String, String> attributes = new LinkedHashMap<>();
- final String subjectPrincipal =
certificate.getSubjectX500Principal().getName();
- final String issuerPrincipal =
certificate.getIssuerX500Principal().getName();
+ final PrincipalFormatter principalFormatter =
StandardPrincipalFormatter.getInstance();
+ final String subjectPrincipal =
principalFormatter.getSubject(certificate);
+ final String issuerPrincipal =
principalFormatter.getIssuer(certificate);
attributes.put(CertificateAttribute.HTTP_SUBJECT_DN.getName(),
subjectPrincipal);
attributes.put(CertificateAttribute.HTTP_ISSUER_DN.getName(),
issuerPrincipal);
diff --git
a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/servlets/ContentAcknowledgmentServlet.java
b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/servlets/ContentAcknowledgmentServlet.java
index 2d82e71bd8..3106d521ab 100644
---
a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/servlets/ContentAcknowledgmentServlet.java
+++
b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/servlets/ContentAcknowledgmentServlet.java
@@ -34,6 +34,7 @@ import org.apache.nifi.processor.ProcessSession;
import org.apache.nifi.processor.Processor;
import org.apache.nifi.processors.standard.ListenHTTP;
import org.apache.nifi.processors.standard.ListenHTTP.FlowFileEntryTimeWrapper;
+import org.apache.nifi.security.cert.StandardPrincipalFormatter;
import org.apache.nifi.util.FormatUtils;
@Path("/holds/*")
@@ -71,12 +72,12 @@ public class ContentAcknowledgmentServlet extends
HttpServlet {
String foundSubject = DEFAULT_FOUND_SUBJECT;
if (certs != null) {
for (final X509Certificate cert : certs) {
- foundSubject = cert.getSubjectX500Principal().getName();
+ foundSubject =
StandardPrincipalFormatter.getInstance().getSubject(cert);
if (authorizedPattern.matcher(foundSubject).matches()) {
break;
} else {
- logger.warn(processor + " rejecting transfer attempt from
" + foundSubject + " because the DN is not authorized");
+ logger.warn("rejecting transfer attempt from [{}] because
the DN is not authorized", foundSubject);
response.sendError(HttpServletResponse.SC_FORBIDDEN, "not
allowed based on dn");
return;
}
diff --git
a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/servlets/ListenHTTPServlet.java
b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/servlets/ListenHTTPServlet.java
index e882d99d61..1419b82cc3 100644
---
a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/servlets/ListenHTTPServlet.java
+++
b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/servlets/ListenHTTPServlet.java
@@ -61,6 +61,8 @@ import org.apache.nifi.processors.standard.ListenHTTP;
import org.apache.nifi.processors.standard.ListenHTTP.FlowFileEntryTimeWrapper;
import org.apache.nifi.processors.standard.exception.ListenHttpException;
import org.apache.nifi.schema.access.SchemaNotFoundException;
+import org.apache.nifi.security.cert.PrincipalFormatter;
+import org.apache.nifi.security.cert.StandardPrincipalFormatter;
import org.apache.nifi.serialization.MalformedRecordException;
import org.apache.nifi.serialization.RecordReader;
import org.apache.nifi.serialization.RecordReaderFactory;
@@ -204,9 +206,10 @@ public class ListenHTTPServlet extends HttpServlet {
foundSubject = DEFAULT_FOUND_SUBJECT;
foundIssuer = DEFAULT_FOUND_ISSUER;
if (certs != null) {
+ final PrincipalFormatter principalFormatter =
StandardPrincipalFormatter.getInstance();
for (final X509Certificate cert : certs) {
- foundSubject = cert.getSubjectX500Principal().getName();
- foundIssuer = cert.getIssuerX500Principal().getName();
+ foundSubject = principalFormatter.getSubject(cert);
+ foundIssuer = principalFormatter.getIssuer(cert);
if (authorizedPattern.matcher(foundSubject).matches()) {
if
(authorizedIssuerPattern.matcher(foundIssuer).matches()) {
break;
diff --git
a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/http/HandleHttpRequestCertificateAttributesProviderTest.java
b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/http/HandleHttpRequestCertificateAttributesProviderTest.java
index 92242edc40..edfd881171 100644
---
a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/http/HandleHttpRequestCertificateAttributesProviderTest.java
+++
b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/http/HandleHttpRequestCertificateAttributesProviderTest.java
@@ -39,9 +39,13 @@ import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class HandleHttpRequestCertificateAttributesProviderTest {
- private static final X500Principal SUBJECT_PRINCIPAL = new
X500Principal("CN=subject, OU=users");
+ private static final String SUBJECT_FORMATTED = "CN=subject, OU=users";
- private static final X500Principal ISSUER_PRINCIPAL = new
X500Principal("CN=issuer, OU=authorities");
+ private static final X500Principal SUBJECT_PRINCIPAL = new
X500Principal(SUBJECT_FORMATTED);
+
+ private static final String ISSUER_FORMATTED = "CN=issuer, OU=authorities";
+
+ private static final X500Principal ISSUER_PRINCIPAL = new
X500Principal(ISSUER_FORMATTED);
private static final String RFC_822_NAME_GENERAL_NAME = "rfc822Name";
@@ -143,7 +147,7 @@ class HandleHttpRequestCertificateAttributesProviderTest {
}
private void assertSubjectIssuerFound(final Map<String, String>
attributes) {
- assertEquals(SUBJECT_PRINCIPAL.getName(),
attributes.get(CertificateAttribute.HTTP_SUBJECT_DN.getName()));
- assertEquals(ISSUER_PRINCIPAL.getName(),
attributes.get(CertificateAttribute.HTTP_ISSUER_DN.getName()));
+ assertEquals(SUBJECT_FORMATTED,
attributes.get(CertificateAttribute.HTTP_SUBJECT_DN.getName()));
+ assertEquals(ISSUER_FORMATTED,
attributes.get(CertificateAttribute.HTTP_ISSUER_DN.getName()));
}
}
diff --git a/nifi-registry/nifi-registry-core/nifi-registry-web-api/pom.xml
b/nifi-registry/nifi-registry-core/nifi-registry-web-api/pom.xml
index 2aa1b6f214..9a1bf653b3 100644
--- a/nifi-registry/nifi-registry-core/nifi-registry-web-api/pom.xml
+++ b/nifi-registry/nifi-registry-core/nifi-registry-web-api/pom.xml
@@ -331,6 +331,11 @@
<artifactId>nifi-registry-security-utils</artifactId>
<version>2.0.0-SNAPSHOT</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.nifi</groupId>
+ <artifactId>nifi-security-cert</artifactId>
+ <version>2.0.0-SNAPSHOT</version>
+ </dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
diff --git
a/nifi-registry/nifi-registry-core/nifi-registry-web-api/src/main/java/org/apache/nifi/registry/web/security/authentication/x509/SubjectDnX509PrincipalExtractor.java
b/nifi-registry/nifi-registry-core/nifi-registry-web-api/src/main/java/org/apache/nifi/registry/web/security/authentication/x509/SubjectDnX509PrincipalExtractor.java
index 69cb62695a..7dcbdbd2c8 100644
---
a/nifi-registry/nifi-registry-core/nifi-registry-web-api/src/main/java/org/apache/nifi/registry/web/security/authentication/x509/SubjectDnX509PrincipalExtractor.java
+++
b/nifi-registry/nifi-registry-core/nifi-registry-web-api/src/main/java/org/apache/nifi/registry/web/security/authentication/x509/SubjectDnX509PrincipalExtractor.java
@@ -16,6 +16,7 @@
*/
package org.apache.nifi.registry.web.security.authentication.x509;
+import org.apache.nifi.security.cert.StandardPrincipalFormatter;
import
org.springframework.security.web.authentication.preauth.x509.X509PrincipalExtractor;
import org.springframework.stereotype.Component;
@@ -28,8 +29,7 @@ import java.security.cert.X509Certificate;
public class SubjectDnX509PrincipalExtractor implements X509PrincipalExtractor
{
@Override
- public Object extractPrincipal(X509Certificate cert) {
- return cert.getSubjectX500Principal().getName().trim();
+ public Object extractPrincipal(final X509Certificate cert) {
+ return StandardPrincipalFormatter.getInstance().getSubject(cert);
}
-
}