This is an automated email from the ASF dual-hosted git repository.
pvillard 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 e2868d64f0 NIFI-15085 Removed OCSP Certificate Validation
e2868d64f0 is described below
commit e2868d64f0f69054f15aea435019a2f1a941a9e9
Author: exceptionfactory <[email protected]>
AuthorDate: Fri Oct 10 21:09:45 2025 -0500
NIFI-15085 Removed OCSP Certificate Validation
- Removed nifi.security.ocsp.responder application properties
- Removed unused dependencies from web-security module supporting OCSP
validation
- Simplified X509AuthenticationProvider
Signed-off-by: Pierre Villard <[email protected]>
This closes #10413.
---
.../service/MiNiFiPropertiesGenerator.java | 2 -
.../resources/MINIFI-216/nifi.properties.before | 2 -
.../resources/MINIFI-245/nifi.properties.before | 3 -
.../src/test/resources/MINIFI-277/nifi.properties | 3 -
.../resources/NIFI-8753/nifi.properties.before | 3 -
.../java/org/apache/nifi/util/NiFiProperties.java | 2 -
.../src/main/asciidoc/administration-guide.adoc | 2 -
.../src/test/resources/nifi.properties | 2 -
.../src/test/resources/nifi.properties | 2 -
.../nifi-framework/nifi-resources/pom.xml | 3 -
.../src/main/resources/conf/nifi.properties | 2 -
.../test/resources/site-to-site/nifi.properties | 2 -
.../nifi-web/nifi-web-security/pom.xml | 30 --
.../X509AuthenticationSecurityConfiguration.java | 25 +-
.../cookie/StandardApplicationCookieService.java | 5 +-
.../security/x509/X509AuthenticationProvider.java | 23 +-
.../security/x509/X509CertificateValidator.java | 54 ---
.../web/security/x509/X509IdentityProvider.java | 94 -----
.../x509/ocsp/CertificateStatusException.java | 42 --
.../x509/ocsp/OcspCertificateValidator.java | 433 ---------------------
.../nifi/web/security/x509/ocsp/OcspRequest.java | 77 ----
.../nifi/web/security/x509/ocsp/OcspStatus.java | 80 ----
.../StandardApplicationCookieServiceTest.java | 15 +-
.../StandardRegistrationBuilderProviderTest.java | 6 +-
.../x509/X509AuthenticationProviderTest.java | 37 +-
.../x509/ocsp/OcspCertificateValidatorTest.java | 230 -----------
.../resources/conf/clustered/node1/nifi.properties | 2 -
.../resources/conf/clustered/node2/nifi.properties | 2 -
.../test/resources/conf/default/nifi.properties | 2 -
.../test/resources/conf/pythonic/nifi.properties | 2 -
30 files changed, 34 insertions(+), 1153 deletions(-)
diff --git
a/minifi/minifi-bootstrap/src/main/java/org/apache/nifi/minifi/bootstrap/service/MiNiFiPropertiesGenerator.java
b/minifi/minifi-bootstrap/src/main/java/org/apache/nifi/minifi/bootstrap/service/MiNiFiPropertiesGenerator.java
index 62371c7956..180d7a7c0a 100644
---
a/minifi/minifi-bootstrap/src/main/java/org/apache/nifi/minifi/bootstrap/service/MiNiFiPropertiesGenerator.java
+++
b/minifi/minifi-bootstrap/src/main/java/org/apache/nifi/minifi/bootstrap/service/MiNiFiPropertiesGenerator.java
@@ -133,8 +133,6 @@ public class MiNiFiPropertiesGenerator {
Triple.of(NiFiProperties.SECURITY_TRUSTSTORE, EMPTY, EMPTY),
Triple.of(NiFiProperties.SECURITY_TRUSTSTORE_TYPE, EMPTY, EMPTY),
Triple.of(NiFiProperties.SECURITY_TRUSTSTORE_PASSWD, EMPTY, EMPTY),
- Triple.of(NiFiProperties.SECURITY_OCSP_RESPONDER_URL, EMPTY, EMPTY),
- Triple.of(NiFiProperties.SECURITY_OCSP_RESPONDER_CERTIFICATE, EMPTY,
EMPTY),
Triple.of(NiFiProperties.CLUSTER_IS_NODE, "false", EMPTY),
Triple.of(NiFiProperties.FLOW_CONFIGURATION_FILE,
"./conf/flow.json.gz", EMPTY)
);
diff --git
a/minifi/minifi-bootstrap/src/test/resources/MINIFI-216/nifi.properties.before
b/minifi/minifi-bootstrap/src/test/resources/MINIFI-216/nifi.properties.before
index 47e5b9889d..1aa7eee8a9 100644
---
a/minifi/minifi-bootstrap/src/test/resources/MINIFI-216/nifi.properties.before
+++
b/minifi/minifi-bootstrap/src/test/resources/MINIFI-216/nifi.properties.before
@@ -104,8 +104,6 @@ nifi.security.user.login.identity.provider=
nifi.security.support.new.account.requests=
# Valid Authorities include:
ROLE_MONITOR,ROLE_DFM,ROLE_ADMIN,ROLE_PROVENANCE,ROLE_NIFI
nifi.security.anonymous.authorities=
-nifi.security.ocsp.responder.url=
-nifi.security.ocsp.responder.certificate=
# cluster node properties (only configure for cluster nodes) #
diff --git
a/minifi/minifi-bootstrap/src/test/resources/MINIFI-245/nifi.properties.before
b/minifi/minifi-bootstrap/src/test/resources/MINIFI-245/nifi.properties.before
index 47e5b9889d..5900cb5477 100644
---
a/minifi/minifi-bootstrap/src/test/resources/MINIFI-245/nifi.properties.before
+++
b/minifi/minifi-bootstrap/src/test/resources/MINIFI-245/nifi.properties.before
@@ -104,9 +104,6 @@ nifi.security.user.login.identity.provider=
nifi.security.support.new.account.requests=
# Valid Authorities include:
ROLE_MONITOR,ROLE_DFM,ROLE_ADMIN,ROLE_PROVENANCE,ROLE_NIFI
nifi.security.anonymous.authorities=
-nifi.security.ocsp.responder.url=
-nifi.security.ocsp.responder.certificate=
-
# cluster node properties (only configure for cluster nodes) #
nifi.cluster.is.node=false
diff --git
a/minifi/minifi-bootstrap/src/test/resources/MINIFI-277/nifi.properties
b/minifi/minifi-bootstrap/src/test/resources/MINIFI-277/nifi.properties
index 47e5b9889d..5900cb5477 100644
--- a/minifi/minifi-bootstrap/src/test/resources/MINIFI-277/nifi.properties
+++ b/minifi/minifi-bootstrap/src/test/resources/MINIFI-277/nifi.properties
@@ -104,9 +104,6 @@ nifi.security.user.login.identity.provider=
nifi.security.support.new.account.requests=
# Valid Authorities include:
ROLE_MONITOR,ROLE_DFM,ROLE_ADMIN,ROLE_PROVENANCE,ROLE_NIFI
nifi.security.anonymous.authorities=
-nifi.security.ocsp.responder.url=
-nifi.security.ocsp.responder.certificate=
-
# cluster node properties (only configure for cluster nodes) #
nifi.cluster.is.node=false
diff --git
a/minifi/minifi-bootstrap/src/test/resources/NIFI-8753/nifi.properties.before
b/minifi/minifi-bootstrap/src/test/resources/NIFI-8753/nifi.properties.before
index 47e5b9889d..5900cb5477 100644
---
a/minifi/minifi-bootstrap/src/test/resources/NIFI-8753/nifi.properties.before
+++
b/minifi/minifi-bootstrap/src/test/resources/NIFI-8753/nifi.properties.before
@@ -104,9 +104,6 @@ nifi.security.user.login.identity.provider=
nifi.security.support.new.account.requests=
# Valid Authorities include:
ROLE_MONITOR,ROLE_DFM,ROLE_ADMIN,ROLE_PROVENANCE,ROLE_NIFI
nifi.security.anonymous.authorities=
-nifi.security.ocsp.responder.url=
-nifi.security.ocsp.responder.certificate=
-
# cluster node properties (only configure for cluster nodes) #
nifi.cluster.is.node=false
diff --git
a/nifi-commons/nifi-properties/src/main/java/org/apache/nifi/util/NiFiProperties.java
b/nifi-commons/nifi-properties/src/main/java/org/apache/nifi/util/NiFiProperties.java
index 9e85c05d22..051981efcc 100644
---
a/nifi-commons/nifi-properties/src/main/java/org/apache/nifi/util/NiFiProperties.java
+++
b/nifi-commons/nifi-properties/src/main/java/org/apache/nifi/util/NiFiProperties.java
@@ -152,8 +152,6 @@ public class NiFiProperties extends ApplicationProperties {
public static final String SECURITY_USER_AUTHORIZER =
"nifi.security.user.authorizer";
public static final String SECURITY_ANONYMOUS_AUTHENTICATION =
"nifi.security.allow.anonymous.authentication";
public static final String SECURITY_USER_LOGIN_IDENTITY_PROVIDER =
"nifi.security.user.login.identity.provider";
- public static final String SECURITY_OCSP_RESPONDER_URL =
"nifi.security.ocsp.responder.url";
- public static final String SECURITY_OCSP_RESPONDER_CERTIFICATE =
"nifi.security.ocsp.responder.certificate";
public static final String SECURITY_IDENTITY_MAPPING_PATTERN_PREFIX =
"nifi.security.identity.mapping.pattern.";
public static final String SECURITY_IDENTITY_MAPPING_VALUE_PREFIX =
"nifi.security.identity.mapping.value.";
public static final String SECURITY_IDENTITY_MAPPING_TRANSFORM_PREFIX =
"nifi.security.identity.mapping.transform.";
diff --git a/nifi-docs/src/main/asciidoc/administration-guide.adoc
b/nifi-docs/src/main/asciidoc/administration-guide.adoc
index 53cbb790af..d818c4a044 100644
--- a/nifi-docs/src/main/asciidoc/administration-guide.adoc
+++ b/nifi-docs/src/main/asciidoc/administration-guide.adoc
@@ -3552,8 +3552,6 @@ These properties pertain to various security features in
NiFi. Many of these pro
|`nifi.security.user.authorizer`|Specifies which of the configured Authorizers
in the _authorizers.xml_ file to use. By default, it is set to
`single-user-authorizer`.
|`nifi.security.allow.anonymous.authentication`|Whether anonymous
authentication is allowed when running over HTTPS. If set to true, client
certificates are not required to connect via TLS. The default value is `false`.
|`nifi.security.user.login.identity.provider`|This indicates what type of
login identity provider to use. It can be set to the identifier from a provider
in the file specified in `nifi.login.identity.provider.configuration.file`.
Setting this property will trigger NiFi to support username/password
authentication. The default value is `single-user-provider`.
-|`nifi.security.ocsp.responder.url`|This is the URL for the Online Certificate
Status Protocol (OCSP) responder if one is being used. It is blank by default.
-|`nifi.security.ocsp.responder.certificate`|This is the location of the OCSP
responder certificate if one is being used. It is blank by default.
|====
=== Identity Mapping Properties
diff --git
a/nifi-framework-bundle/nifi-framework/nifi-framework-nar-utils/src/test/resources/nifi.properties
b/nifi-framework-bundle/nifi-framework/nifi-framework-nar-utils/src/test/resources/nifi.properties
index 97af4a3ad9..960c93ac54 100644
---
a/nifi-framework-bundle/nifi-framework/nifi-framework-nar-utils/src/test/resources/nifi.properties
+++
b/nifi-framework-bundle/nifi-framework/nifi-framework-nar-utils/src/test/resources/nifi.properties
@@ -132,8 +132,6 @@ nifi.security.truststoreType=
nifi.security.truststorePasswd=
nifi.security.user.authorizer=file-provider
nifi.security.user.login.identity.provider=
-nifi.security.ocsp.responder.url=
-nifi.security.ocsp.responder.certificate=
# Identity Mapping Properties #
# These properties allow normalizing user identities such that identities
coming from different identity providers
diff --git
a/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/resources/nifi.properties
b/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/resources/nifi.properties
index 858c1e5cc9..d379987a03 100644
---
a/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/resources/nifi.properties
+++
b/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/resources/nifi.properties
@@ -132,8 +132,6 @@ nifi.security.truststoreType=
nifi.security.truststorePasswd=
nifi.security.user.authorizer=file-provider
nifi.security.user.login.identity.provider=
-nifi.security.ocsp.responder.url=
-nifi.security.ocsp.responder.certificate=
# Identity Mapping Properties #
# These properties allow normalizing user identities such that identities
coming from different identity providers
diff --git a/nifi-framework-bundle/nifi-framework/nifi-resources/pom.xml
b/nifi-framework-bundle/nifi-framework/nifi-resources/pom.xml
index db03b072d8..259bbcfd16 100644
--- a/nifi-framework-bundle/nifi-framework/nifi-resources/pom.xml
+++ b/nifi-framework-bundle/nifi-framework/nifi-resources/pom.xml
@@ -161,9 +161,6 @@
<nifi.security.allow.anonymous.authentication>false</nifi.security.allow.anonymous.authentication>
<nifi.security.user.login.identity.provider>single-user-provider</nifi.security.user.login.identity.provider>
<nifi.security.user.jws.key.rotation.period>PT1H</nifi.security.user.jws.key.rotation.period>
- <nifi.security.x509.principal.extractor />
- <nifi.security.ocsp.responder.url />
- <nifi.security.ocsp.responder.certificate />
<!-- nifi.properties: openid connect -->
<nifi.security.user.oidc.discovery.url />
diff --git
a/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/conf/nifi.properties
b/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/conf/nifi.properties
index 8161e124d5..59a6eda4cc 100644
---
a/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/conf/nifi.properties
+++
b/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/conf/nifi.properties
@@ -204,8 +204,6 @@
nifi.security.user.authorizer=${nifi.security.user.authorizer}
nifi.security.allow.anonymous.authentication=${nifi.security.allow.anonymous.authentication}
nifi.security.user.login.identity.provider=${nifi.security.user.login.identity.provider}
nifi.security.user.jws.key.rotation.period=${nifi.security.user.jws.key.rotation.period}
-nifi.security.ocsp.responder.url=${nifi.security.ocsp.responder.url}
-nifi.security.ocsp.responder.certificate=${nifi.security.ocsp.responder.certificate}
# OpenId Connect SSO Properties #
nifi.security.user.oidc.discovery.url=${nifi.security.user.oidc.discovery.url}
diff --git
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/resources/site-to-site/nifi.properties
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/resources/site-to-site/nifi.properties
index 4c0274f941..b0546cb524 100644
---
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/resources/site-to-site/nifi.properties
+++
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/resources/site-to-site/nifi.properties
@@ -132,8 +132,6 @@ nifi.security.truststoreType=${nifi.security.truststoreType}
nifi.security.truststorePasswd=${nifi.security.truststorePasswd}
nifi.security.user.authorizer=${nifi.security.user.authorizer}
nifi.security.user.login.identity.provider=${nifi.security.user.login.identity.provider}
-nifi.security.ocsp.responder.url=${nifi.security.ocsp.responder.url}
-nifi.security.ocsp.responder.certificate=${nifi.security.ocsp.responder.certificate}
# cluster common properties (all nodes must have same values) #
nifi.cluster.protocol.heartbeat.interval=${nifi.cluster.protocol.heartbeat.interval}
diff --git
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/pom.xml
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/pom.xml
index 74bb93ac2f..d8366492f9 100644
--- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/pom.xml
+++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/pom.xml
@@ -101,11 +101,6 @@
<artifactId>nifi-web-servlet-shared</artifactId>
<version>2.7.0-SNAPSHOT</version>
</dependency>
- <dependency>
- <groupId>org.apache.nifi</groupId>
- <artifactId>nifi-web-utils</artifactId>
- <version>2.7.0-SNAPSHOT</version>
- </dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-security-identity</artifactId>
@@ -165,18 +160,10 @@
<artifactId>nifi-xml-processing</artifactId>
<version>2.7.0-SNAPSHOT</version>
</dependency>
- <dependency>
- <groupId>org.bouncycastle</groupId>
- <artifactId>bcprov-jdk18on</artifactId>
- </dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
- <dependency>
- <groupId>org.bouncycastle</groupId>
- <artifactId>bcpkix-jdk18on</artifactId>
- </dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
@@ -265,18 +252,6 @@
<groupId>com.nimbusds</groupId>
<artifactId>oauth2-oidc-sdk</artifactId>
</dependency>
- <dependency>
- <groupId>jakarta.ws.rs</groupId>
- <artifactId>jakarta.ws.rs-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.glassfish.jersey.core</groupId>
- <artifactId>jersey-client</artifactId>
- </dependency>
- <dependency>
- <groupId>org.glassfish.jersey.media</groupId>
- <artifactId>jersey-media-json-jackson</artifactId>
- </dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
@@ -293,11 +268,6 @@
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
- <dependency>
- <groupId>commons-io</groupId>
- <artifactId>commons-io</artifactId>
- <scope>test</scope>
- </dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-web-client-api</artifactId>
diff --git
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/configuration/X509AuthenticationSecurityConfiguration.java
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/configuration/X509AuthenticationSecurityConfiguration.java
index 17f79286cf..6de40dc75c 100644
---
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/configuration/X509AuthenticationSecurityConfiguration.java
+++
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/configuration/X509AuthenticationSecurityConfiguration.java
@@ -24,9 +24,6 @@ import
org.apache.nifi.web.security.x509.SubjectDnX509PrincipalExtractor;
import org.apache.nifi.web.security.x509.X509AuthenticationFilter;
import org.apache.nifi.web.security.x509.X509AuthenticationProvider;
import org.apache.nifi.web.security.x509.X509CertificateExtractor;
-import org.apache.nifi.web.security.x509.X509CertificateValidator;
-import org.apache.nifi.web.security.x509.X509IdentityProvider;
-import org.apache.nifi.web.security.x509.ocsp.OcspCertificateValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -66,7 +63,7 @@ public class X509AuthenticationSecurityConfiguration {
@Bean
public X509AuthenticationProvider x509AuthenticationProvider() {
- return new X509AuthenticationProvider(certificateIdentityProvider(),
authorizer, niFiProperties);
+ return new X509AuthenticationProvider(authorizer, niFiProperties);
}
@Bean
@@ -78,24 +75,4 @@ public class X509AuthenticationSecurityConfiguration {
public X509PrincipalExtractor principalExtractor() {
return new SubjectDnX509PrincipalExtractor();
}
-
- @Bean
- public OcspCertificateValidator ocspValidator() {
- return new OcspCertificateValidator(niFiProperties);
- }
-
- @Bean
- public X509CertificateValidator certificateValidator() {
- final X509CertificateValidator certificateValidator = new
X509CertificateValidator();
- certificateValidator.setOcspValidator(ocspValidator());
- return certificateValidator;
- }
-
- @Bean
- public X509IdentityProvider certificateIdentityProvider() {
- final X509IdentityProvider identityProvider = new
X509IdentityProvider();
- identityProvider.setCertificateValidator(certificateValidator());
- identityProvider.setPrincipalExtractor(principalExtractor());
- return identityProvider;
- }
}
diff --git
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/cookie/StandardApplicationCookieService.java
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/cookie/StandardApplicationCookieService.java
index e5ef47939e..934f59f050 100644
---
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/cookie/StandardApplicationCookieService.java
+++
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/cookie/StandardApplicationCookieService.java
@@ -25,7 +25,6 @@ import org.springframework.web.util.WebUtils;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
-import jakarta.ws.rs.core.HttpHeaders;
import java.net.URI;
import java.time.Duration;
import java.util.Objects;
@@ -47,6 +46,8 @@ public class StandardApplicationCookieService implements
ApplicationCookieServic
private static final boolean HTTP_ONLY_ENABLED = true;
+ private static final String SET_COOKIE_HEADER = "Set-Cookie";
+
private static final Logger logger =
LoggerFactory.getLogger(StandardApplicationCookieService.class);
/**
@@ -134,7 +135,7 @@ public class StandardApplicationCookieService implements
ApplicationCookieServic
}
private void setResponseCookie(final HttpServletResponse response, final
ResponseCookie responseCookie) {
- response.addHeader(HttpHeaders.SET_COOKIE, responseCookie.toString());
+ response.addHeader(SET_COOKIE_HEADER, responseCookie.toString());
}
private String getCookiePath(final URI resourceUri) {
diff --git
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/X509AuthenticationProvider.java
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/X509AuthenticationProvider.java
index 8caed9a2ca..9d90e1984a 100644
---
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/X509AuthenticationProvider.java
+++
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/X509AuthenticationProvider.java
@@ -28,6 +28,8 @@ import org.apache.nifi.authorization.user.NiFiUser;
import org.apache.nifi.authorization.user.NiFiUserDetails;
import org.apache.nifi.authorization.user.StandardNiFiUser;
import org.apache.nifi.authorization.user.StandardNiFiUser.Builder;
+import org.apache.nifi.security.cert.PrincipalFormatter;
+import org.apache.nifi.security.cert.StandardPrincipalFormatter;
import org.apache.nifi.util.NiFiProperties;
import org.apache.nifi.web.security.InvalidAuthenticationException;
import org.apache.nifi.web.security.NiFiAuthenticationProvider;
@@ -45,6 +47,7 @@ import java.util.Collections;
import java.util.List;
import java.util.ListIterator;
import java.util.Set;
+import java.util.concurrent.TimeUnit;
/**
*
@@ -65,13 +68,13 @@ public class X509AuthenticationProvider extends
NiFiAuthenticationProvider {
}
};
- private X509IdentityProvider certificateIdentityProvider;
- private Authorizer authorizer;
+ private static final PrincipalFormatter principalFormatter =
StandardPrincipalFormatter.getInstance();
+
+ private final Authorizer authorizer;
final NiFiProperties properties;
- public X509AuthenticationProvider(final X509IdentityProvider
certificateIdentityProvider, final Authorizer authorizer, final NiFiProperties
nifiProperties) {
+ public X509AuthenticationProvider(final Authorizer authorizer, final
NiFiProperties nifiProperties) {
super(nifiProperties, authorizer);
- this.certificateIdentityProvider = certificateIdentityProvider;
this.authorizer = authorizer;
this.properties = nifiProperties;
}
@@ -80,14 +83,12 @@ public class X509AuthenticationProvider extends
NiFiAuthenticationProvider {
public Authentication authenticate(Authentication authentication) throws
AuthenticationException {
final X509AuthenticationRequestToken request =
(X509AuthenticationRequestToken) authentication;
- // attempt to authenticate if certificates were found
final X509Certificate[] certificates = request.getCertificates();
- final AuthenticationResponse authenticationResponse;
- try {
- authenticationResponse =
certificateIdentityProvider.authenticate(certificates);
- } catch (final IllegalArgumentException iae) {
- throw new InvalidAuthenticationException(iae.getMessage(), iae);
- }
+ final X509Certificate peerCertificate = certificates[0];
+
+ final String principal =
principalFormatter.getSubject(peerCertificate);
+ final String issuer = principalFormatter.getIssuer(peerCertificate);
+ final AuthenticationResponse authenticationResponse = new
AuthenticationResponse(principal, principal, TimeUnit.MILLISECONDS.convert(12,
TimeUnit.HOURS), issuer);
if (StringUtils.isBlank(request.getProxiedEntitiesChain())) {
final String mappedIdentity =
mapIdentity(authenticationResponse.getIdentity());
diff --git
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/X509CertificateValidator.java
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/X509CertificateValidator.java
deleted file mode 100644
index 511c5e5e63..0000000000
---
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/X509CertificateValidator.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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.web.security.x509;
-
-import java.security.cert.CertificateExpiredException;
-import java.security.cert.CertificateNotYetValidException;
-import java.security.cert.X509Certificate;
-import org.apache.nifi.web.security.x509.ocsp.CertificateStatusException;
-import org.apache.nifi.web.security.x509.ocsp.OcspCertificateValidator;
-
-/**
- * Extracts client certificates from Http requests.
- */
-public class X509CertificateValidator {
-
- private OcspCertificateValidator ocspValidator;
-
- /**
- * Extract the client certificate from the specified HttpServletRequest or
null if none is specified.
- *
- * @param certificates the client certificates
- * @throws java.security.cert.CertificateExpiredException cert is expired
- * @throws java.security.cert.CertificateNotYetValidException cert is not
yet valid
- * @throws
org.apache.nifi.web.security.x509.ocsp.CertificateStatusException ocsp
validation issue
- */
- public void validateClientCertificate(final X509Certificate[] certificates)
- throws CertificateExpiredException,
CertificateNotYetValidException, CertificateStatusException {
-
- // ensure the cert is valid
- certificates[0].checkValidity();
-
- // perform ocsp validator if necessary
- ocspValidator.validate(certificates);
- }
-
- public void setOcspValidator(OcspCertificateValidator ocspValidator) {
- this.ocspValidator = ocspValidator;
- }
-
-}
diff --git
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/X509IdentityProvider.java
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/X509IdentityProvider.java
deleted file mode 100644
index c20a28e045..0000000000
---
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/X509IdentityProvider.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * 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.web.security.x509;
-
-import java.security.cert.CertificateExpiredException;
-import java.security.cert.CertificateNotYetValidException;
-import java.security.cert.X509Certificate;
-import java.util.concurrent.TimeUnit;
-import org.apache.nifi.authentication.AuthenticationResponse;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import
org.springframework.security.web.authentication.preauth.x509.X509PrincipalExtractor;
-
-/**
- * Identity provider for extract the authenticating a ServletRequest with a
X509Certificate.
- */
-public class X509IdentityProvider {
-
- private static final Logger logger =
LoggerFactory.getLogger(X509IdentityProvider.class);
-
- private final String issuer = getClass().getSimpleName();
-
- private X509CertificateValidator certificateValidator;
- private X509PrincipalExtractor principalExtractor;
-
- /**
- * Authenticates the specified request by checking certificate validity.
- *
- * @param certificates the client certificates
- * @return an authentication response
- * @throws IllegalArgumentException the request did not contain a valid
certificate (or no certificate)
- */
- public AuthenticationResponse authenticate(final X509Certificate[]
certificates) throws IllegalArgumentException {
- // ensure the cert was found
- if (certificates == null || certificates.length == 0) {
- throw new IllegalArgumentException("The specified request does not
contain a client certificate.");
- }
-
- // extract the principal
- final Object certificatePrincipal =
principalExtractor.extractPrincipal(certificates[0]);
- final String principal = certificatePrincipal.toString();
-
- try {
- certificateValidator.validateClientCertificate(certificates);
- } catch (CertificateExpiredException cee) {
- final String message = String.format("Client certificate for (%s)
is expired.", principal);
- logger.info(message, cee);
- if (logger.isDebugEnabled()) {
- logger.debug("", cee);
- }
- throw new IllegalArgumentException(message, cee);
- } catch (CertificateNotYetValidException cnyve) {
- final String message = String.format("Client certificate for (%s)
is not yet valid.", principal);
- logger.info(message, cnyve);
- if (logger.isDebugEnabled()) {
- logger.debug("", cnyve);
- }
- throw new IllegalArgumentException(message, cnyve);
- } catch (final Exception e) {
- logger.info(e.getMessage());
- if (logger.isDebugEnabled()) {
- logger.debug("", e);
- }
- throw new IllegalArgumentException(e.getMessage(), e);
- }
-
- // build the authentication response
- return new AuthenticationResponse(principal, principal,
TimeUnit.MILLISECONDS.convert(12, TimeUnit.HOURS), issuer);
- }
-
- /* setters */
- public void setCertificateValidator(X509CertificateValidator
certificateValidator) {
- this.certificateValidator = certificateValidator;
- }
-
- public void setPrincipalExtractor(X509PrincipalExtractor
principalExtractor) {
- this.principalExtractor = principalExtractor;
- }
-
-}
diff --git
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/ocsp/CertificateStatusException.java
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/ocsp/CertificateStatusException.java
deleted file mode 100644
index 61b57233a2..0000000000
---
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/ocsp/CertificateStatusException.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.web.security.x509.ocsp;
-
-/**
- * Represents the exceptional case when a users certificate status is not GOOD.
- */
-public class CertificateStatusException extends Exception {
-
- public CertificateStatusException() {
- }
-
- public CertificateStatusException(String message) {
- super(message);
- }
-
- public CertificateStatusException(String message, Throwable cause) {
- super(message, cause);
- }
-
- public CertificateStatusException(Throwable cause) {
- super(cause);
- }
-
- public CertificateStatusException(String message, Throwable cause, boolean
enableSuppression, boolean writableStackTrace) {
- super(message, cause, enableSuppression, writableStackTrace);
- }
-}
diff --git
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/ocsp/OcspCertificateValidator.java
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/ocsp/OcspCertificateValidator.java
deleted file mode 100644
index 7d9979c8d6..0000000000
---
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/ocsp/OcspCertificateValidator.java
+++ /dev/null
@@ -1,433 +0,0 @@
-/*
- * 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.web.security.x509.ocsp;
-
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.math.BigInteger;
-import java.net.URI;
-import java.security.KeyStore;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.TrustManagerFactory;
-import javax.net.ssl.X509TrustManager;
-import javax.security.auth.x500.X500Principal;
-import jakarta.ws.rs.ProcessingException;
-import jakarta.ws.rs.client.Client;
-import jakarta.ws.rs.client.Entity;
-import jakarta.ws.rs.client.WebTarget;
-import jakarta.ws.rs.core.Response;
-
-import com.github.benmanes.caffeine.cache.Caffeine;
-import com.github.benmanes.caffeine.cache.LoadingCache;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.nifi.deprecation.log.DeprecationLogger;
-import org.apache.nifi.deprecation.log.DeprecationLoggerFactory;
-import org.apache.nifi.util.FormatUtils;
-import org.apache.nifi.util.NiFiProperties;
-import org.apache.nifi.web.security.x509.ocsp.OcspStatus.ValidationStatus;
-import org.apache.nifi.web.security.x509.ocsp.OcspStatus.VerificationStatus;
-import org.apache.nifi.web.util.WebClientUtils;
-import org.bouncycastle.asn1.DEROctetString;
-import org.bouncycastle.asn1.ocsp.OCSPObjectIdentifiers;
-import org.bouncycastle.asn1.x509.Extension;
-import org.bouncycastle.asn1.x509.Extensions;
-import org.bouncycastle.cert.X509CertificateHolder;
-import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
-import org.bouncycastle.cert.ocsp.BasicOCSPResp;
-import org.bouncycastle.cert.ocsp.CertificateID;
-import org.bouncycastle.cert.ocsp.CertificateStatus;
-import org.bouncycastle.cert.ocsp.OCSPException;
-import org.bouncycastle.cert.ocsp.OCSPReq;
-import org.bouncycastle.cert.ocsp.OCSPReqBuilder;
-import org.bouncycastle.cert.ocsp.OCSPResp;
-import org.bouncycastle.cert.ocsp.OCSPRespBuilder;
-import org.bouncycastle.cert.ocsp.RevokedStatus;
-import org.bouncycastle.cert.ocsp.SingleResp;
-import org.bouncycastle.operator.DigestCalculatorProvider;
-import org.bouncycastle.operator.OperatorCreationException;
-import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder;
-import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
-import org.glassfish.jersey.client.ClientConfig;
-import org.glassfish.jersey.client.ClientProperties;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class OcspCertificateValidator {
-
- private static final Logger logger =
LoggerFactory.getLogger(OcspCertificateValidator.class);
-
- private static final DeprecationLogger deprecationLogger =
DeprecationLoggerFactory.getLogger(OcspCertificateValidator.class);
-
- private static final String OCSP_REQUEST_CONTENT_TYPE =
"application/ocsp-request";
-
- private static final int CONNECT_TIMEOUT = 10000;
- private static final int READ_TIMEOUT = 10000;
-
- private URI validationAuthorityURI;
- private Client client;
- private Map<String, X509Certificate> trustedCAs;
-
- private LoadingCache<OcspRequest, OcspStatus> ocspCache;
-
- public OcspCertificateValidator(final NiFiProperties properties) {
- // get the responder url
- final String rawValidationAuthorityUrl =
properties.getProperty(NiFiProperties.SECURITY_OCSP_RESPONDER_URL);
-
- // set properties when appropriate
- if (StringUtils.isNotBlank(rawValidationAuthorityUrl)) {
- deprecationLogger.warn("OCSP Certificate Validation with Responder
URL [{}] is deprecated for removal",
NiFiProperties.SECURITY_OCSP_RESPONDER_URL);
-
- try {
- // attempt to parse the specified va url
- validationAuthorityURI = URI.create(rawValidationAuthorityUrl);
-
- final ClientConfig clientConfig = new ClientConfig();
- clientConfig.property(ClientProperties.READ_TIMEOUT,
READ_TIMEOUT);
- clientConfig.property(ClientProperties.CONNECT_TIMEOUT,
CONNECT_TIMEOUT);
-
- // initialize the client
- client = WebClientUtils.createClient(clientConfig);
-
- // get the trusted CAs
- trustedCAs = getTrustedCAs(properties);
-
- // consider the ocsp certificate is specified
- final X509Certificate ocspCertificate =
getOcspCertificate(properties);
- if (ocspCertificate != null) {
-
trustedCAs.put(ocspCertificate.getSubjectX500Principal().getName(),
ocspCertificate);
- }
-
- // TODO - determine how long to cache the ocsp responses for
- final long cacheDurationMillis =
FormatUtils.getTimeDuration("12 hours", TimeUnit.MILLISECONDS);
-
- // build the ocsp cache
- ocspCache =
Caffeine.newBuilder().expireAfterWrite(cacheDurationMillis,
TimeUnit.MILLISECONDS).build(ocspRequest -> {
- final String subjectDn =
ocspRequest.getSubjectCertificate().getSubjectX500Principal().getName();
-
- logger.info("Validating client certificate via OCSP:
<{}>", subjectDn);
- final OcspStatus ocspStatus = getOcspStatus(ocspRequest);
- logger.info("Client certificate status for <{}>: {}",
subjectDn, ocspStatus);
-
- return ocspStatus;
- });
- } catch (final Exception e) {
- logger.error("Disabling OCSP certificate validation. Unable to
load OCSP configuration", e);
- client = null;
- }
- }
- }
-
- /**
- * Loads the ocsp certificate if specified. Null otherwise.
- *
- * @param properties nifi properties
- * @return certificate
- */
- private X509Certificate getOcspCertificate(final NiFiProperties
properties) {
- X509Certificate validationAuthorityCertificate = null;
-
- final String validationAuthorityCertificatePath =
properties.getProperty(NiFiProperties.SECURITY_OCSP_RESPONDER_CERTIFICATE);
- if (StringUtils.isNotBlank(validationAuthorityCertificatePath)) {
- try (final FileInputStream fis = new
FileInputStream(validationAuthorityCertificatePath)) {
- final CertificateFactory cf =
CertificateFactory.getInstance("X.509");
- validationAuthorityCertificate = (X509Certificate)
cf.generateCertificate(fis);
- } catch (final Exception e) {
- throw new IllegalStateException("Unable to load the validation
authority certificate: " + e);
- }
- }
-
- return validationAuthorityCertificate;
- }
-
- /**
- * Loads the trusted certificate authorities according to the specified
properties.
- *
- * @param properties properties
- * @return map of certificate authorities
- */
- private Map<String, X509Certificate> getTrustedCAs(final NiFiProperties
properties) {
- final Map<String, X509Certificate> certificateAuthorities = new
HashMap<>();
-
- // get the path to the truststore
- final String truststorePath =
properties.getProperty(NiFiProperties.SECURITY_TRUSTSTORE);
- if (truststorePath == null) {
- throw new IllegalArgumentException("The truststore path is
required.");
- }
-
- // get the truststore password
- final char[] truststorePassword;
- final String rawTruststorePassword =
properties.getProperty(NiFiProperties.SECURITY_TRUSTSTORE_PASSWD);
- if (rawTruststorePassword == null) {
- truststorePassword = new char[0];
- } else {
- truststorePassword = rawTruststorePassword.toCharArray();
- }
-
- // load the configured truststore
- try (final FileInputStream fis = new FileInputStream(truststorePath)) {
- final KeyStore truststore =
KeyStore.getInstance(KeyStore.getDefaultType());
- truststore.load(fis, truststorePassword);
-
- TrustManagerFactory trustManagerFactory =
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
- trustManagerFactory.init(truststore);
-
- // consider any certificates in the truststore as a trusted ca
- for (TrustManager trustManager :
trustManagerFactory.getTrustManagers()) {
- if (trustManager instanceof X509TrustManager) {
- for (X509Certificate ca : ((X509TrustManager)
trustManager).getAcceptedIssuers()) {
-
certificateAuthorities.put(ca.getSubjectX500Principal().getName(), ca);
- }
- }
- }
- } catch (final Exception e) {
- throw new IllegalStateException("Unable to load the configured
truststore: " + e);
- }
-
- return certificateAuthorities;
- }
-
- /**
- * Validates the specified certificate using OCSP if configured.
- *
- * @param certificates the client certificates
- * @throws CertificateStatusException ex
- */
- public void validate(final X509Certificate[] certificates) throws
CertificateStatusException {
- // only validate if configured to do so
- if (client != null && certificates != null && certificates.length > 0)
{
- final X509Certificate subjectCertificate =
getSubjectCertificate(certificates);
- final X509Certificate issuerCertificate =
getIssuerCertificate(certificates);
- if (issuerCertificate == null) {
- throw new IllegalArgumentException(String.format("Unable to
obtain certificate of issuer <%s> for the specified subject certificate <%s>.",
- subjectCertificate.getIssuerX500Principal().getName(),
subjectCertificate.getSubjectX500Principal().getName()));
- }
-
- // create the ocsp status key
- final OcspRequest ocspRequest = new
OcspRequest(subjectCertificate, issuerCertificate);
-
- // determine the status and ensure it isn't verified as revoked
- final OcspStatus ocspStatus = ocspCache.get(ocspRequest);
-
- // we only disallow when we have a verified response that states
the certificate is revoked
- if
(VerificationStatus.Verified.equals(ocspStatus.getVerificationStatus()) &&
ValidationStatus.Revoked.equals(ocspStatus.getValidationStatus())) {
- throw new CertificateStatusException(String.format("Client
certificate for <%s> is revoked according to the certificate authority.",
-
subjectCertificate.getSubjectX500Principal().getName()));
- }
- }
- }
-
- /**
- * Gets the subject certificate.
- *
- * @param certificates certs
- * @return subject cert
- */
- private X509Certificate getSubjectCertificate(final X509Certificate[]
certificates) {
- return certificates[0];
- }
-
- /**
- * Gets the issuer certificate.
- *
- * @param certificates certs
- * @return issuer cert
- */
- private X509Certificate getIssuerCertificate(final X509Certificate[]
certificates) {
- if (certificates.length > 1) {
- return certificates[1];
- } else if (certificates.length == 1) {
- final X509Certificate subjectCertificate =
getSubjectCertificate(certificates);
- final X500Principal issuerPrincipal =
subjectCertificate.getIssuerX500Principal();
- return trustedCAs.get(issuerPrincipal.getName());
- } else {
- return null;
- }
- }
-
- /**
- * Gets the OCSP status for the specified subject and issuer certificates.
- *
- * @param ocspStatusKey status key
- * @return ocsp status
- */
- private OcspStatus getOcspStatus(final OcspRequest ocspStatusKey) {
- final X509Certificate subjectCertificate =
ocspStatusKey.getSubjectCertificate();
- final X509Certificate issuerCertificate =
ocspStatusKey.getIssuerCertificate();
-
- // initialize the default status
- final OcspStatus ocspStatus = new OcspStatus();
- ocspStatus.setVerificationStatus(VerificationStatus.Unknown);
- ocspStatus.setValidationStatus(ValidationStatus.Unknown);
-
- try {
- // prepare the request
- final BigInteger subjectSerialNumber =
subjectCertificate.getSerialNumber();
- final DigestCalculatorProvider calculatorProviderBuilder = new
JcaDigestCalculatorProviderBuilder().setProvider("BC").build();
- final CertificateID certificateId = new
CertificateID(calculatorProviderBuilder.get(CertificateID.HASH_SHA1),
- new X509CertificateHolder(issuerCertificate.getEncoded()),
- subjectSerialNumber);
-
- // generate the request
- final OCSPReqBuilder requestGenerator = new OCSPReqBuilder();
- requestGenerator.addRequest(certificateId);
-
- // Create a nonce to avoid replay attack
- BigInteger nonce = BigInteger.valueOf(System.currentTimeMillis());
- Extension ext = new
Extension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce, true, new
DEROctetString(nonce.toByteArray()));
- requestGenerator.setRequestExtensions(new Extensions(new
Extension[]{ext}));
-
- final OCSPReq ocspRequest = requestGenerator.build();
-
- // perform the request
- final Response response = getClientResponse(ocspRequest);
-
- // ensure the request was completed successfully
- if (Response.Status.OK.getStatusCode() !=
response.getStatusInfo().getStatusCode()) {
- logger.warn("OCSP request was unsuccessful ({}).",
response.getStatus());
- return ocspStatus;
- }
-
- // interpret the response
- OCSPResp ocspResponse = new
OCSPResp(response.readEntity(InputStream.class));
-
- // verify the response status
- switch (ocspResponse.getStatus()) {
- case OCSPRespBuilder.SUCCESSFUL:
-
ocspStatus.setResponseStatus(OcspStatus.ResponseStatus.Successful);
- break;
- case OCSPRespBuilder.INTERNAL_ERROR:
-
ocspStatus.setResponseStatus(OcspStatus.ResponseStatus.InternalError);
- break;
- case OCSPRespBuilder.MALFORMED_REQUEST:
-
ocspStatus.setResponseStatus(OcspStatus.ResponseStatus.MalformedRequest);
- break;
- case OCSPRespBuilder.SIG_REQUIRED:
-
ocspStatus.setResponseStatus(OcspStatus.ResponseStatus.SignatureRequired);
- break;
- case OCSPRespBuilder.TRY_LATER:
-
ocspStatus.setResponseStatus(OcspStatus.ResponseStatus.TryLater);
- break;
- case OCSPRespBuilder.UNAUTHORIZED:
-
ocspStatus.setResponseStatus(OcspStatus.ResponseStatus.Unauthorized);
- break;
- default:
-
ocspStatus.setResponseStatus(OcspStatus.ResponseStatus.Unknown);
- break;
- }
-
- // only proceed if the response was successful
- if (ocspResponse.getStatus() != OCSPRespBuilder.SUCCESSFUL) {
- logger.warn("OCSP request was unsuccessful ({}).",
ocspStatus.getResponseStatus());
- return ocspStatus;
- }
-
- // ensure the appropriate response object
- final Object ocspResponseObject = ocspResponse.getResponseObject();
- if (!(ocspResponseObject instanceof BasicOCSPResp)) {
- logger.warn("Unexpected OCSP response object: {}",
ocspResponseObject);
- return ocspStatus;
- }
-
- // get the response object
- final BasicOCSPResp basicOcspResponse = (BasicOCSPResp)
ocspResponse.getResponseObject();
-
- // attempt to locate the responder certificate
- final X509CertificateHolder[] responderCertificates =
basicOcspResponse.getCerts();
- if (responderCertificates.length != 1) {
- logger.warn("Unexpected number of OCSP responder certificates:
{}", responderCertificates.length);
- return ocspStatus;
- }
-
- // get the responder certificate
- final X509Certificate trustedResponderCertificate =
getTrustedResponderCertificate(responderCertificates[0], issuerCertificate);
- if (trustedResponderCertificate != null) {
- // verify the response
- if (basicOcspResponse.isSignatureValid(new
JcaContentVerifierProviderBuilder().setProvider("BC").build(trustedResponderCertificate.getPublicKey())))
{
-
ocspStatus.setVerificationStatus(VerificationStatus.Verified);
- } else {
-
ocspStatus.setVerificationStatus(VerificationStatus.Unverified);
- }
- } else {
-
ocspStatus.setVerificationStatus(VerificationStatus.Unverified);
- }
-
- // validate the response
- final SingleResp[] responses = basicOcspResponse.getResponses();
- for (SingleResp singleResponse : responses) {
- final CertificateID responseCertificateId =
singleResponse.getCertID();
- final BigInteger responseSerialNumber =
responseCertificateId.getSerialNumber();
-
- if (responseSerialNumber.equals(subjectSerialNumber)) {
- Object certStatus = singleResponse.getCertStatus();
-
- // interpret the certificate status
- if (CertificateStatus.GOOD == certStatus) {
- ocspStatus.setValidationStatus(ValidationStatus.Good);
- } else if (certStatus instanceof RevokedStatus) {
-
ocspStatus.setValidationStatus(ValidationStatus.Revoked);
- } else {
-
ocspStatus.setValidationStatus(ValidationStatus.Unknown);
- }
- }
- }
- } catch (final OCSPException | IOException | ProcessingException |
OperatorCreationException e) {
- logger.error(e.getMessage(), e);
- } catch (CertificateException e) {
- logger.error("Certificate processing failed", e);
- }
-
- return ocspStatus;
- }
-
- private Response getClientResponse(OCSPReq ocspRequest) throws IOException
{
- final WebTarget webTarget = client.target(validationAuthorityURI);
- return
webTarget.request().post(Entity.entity(ocspRequest.getEncoded(),
OCSP_REQUEST_CONTENT_TYPE));
- }
-
- /**
- * Gets the trusted responder certificate. The response contains the
responder certificate, however we cannot blindly trust it. Instead, we use a
configured trusted CA. If the responder
- * certificate is a trusted CA, then we can use it. If the responder
certificate is not directly trusted, we still may be able to trust it if it was
issued by the same CA that issued the subject
- * certificate. Other various checks may be required (this portion is
currently not implemented).
- *
- * @param responderCertificateHolder cert
- * @param issuerCertificate cert
- * @return cert
- */
- private X509Certificate getTrustedResponderCertificate(final
X509CertificateHolder responderCertificateHolder, final X509Certificate
issuerCertificate) throws CertificateException {
- // look for the responder's certificate specifically
- final X509Certificate responderCertificate = new
JcaX509CertificateConverter().setProvider("BC").getCertificate(responderCertificateHolder);
- final String trustedCAName =
responderCertificate.getSubjectX500Principal().getName();
- if (trustedCAs.containsKey(trustedCAName)) {
- return trustedCAs.get(trustedCAName);
- }
-
- // if the responder certificate was issued by the same CA that issued
the subject certificate we may be able to use that...
- final X500Principal issuerCA =
issuerCertificate.getSubjectX500Principal();
- if (responderCertificate.getIssuerX500Principal().equals(issuerCA)) {
- return null;
- } else {
- return null;
- }
- }
-}
diff --git
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/ocsp/OcspRequest.java
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/ocsp/OcspRequest.java
deleted file mode 100644
index ea3d0561ce..0000000000
---
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/ocsp/OcspRequest.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * 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.web.security.x509.ocsp;
-
-import java.security.cert.X509Certificate;
-import java.util.Objects;
-
-/**
- * A request to verify/validate the specified subject certificate via OCSP.
- */
-public class OcspRequest {
-
- private final X509Certificate subjectCertificate;
- private final X509Certificate issuerCertificate;
-
- public OcspRequest(X509Certificate subjectCertificate, X509Certificate
issuerCertificate) {
- this.subjectCertificate = subjectCertificate;
- this.issuerCertificate = issuerCertificate;
- }
-
- public X509Certificate getSubjectCertificate() {
- return subjectCertificate;
- }
-
- public X509Certificate getIssuerCertificate() {
- return issuerCertificate;
- }
-
- @Override
- public int hashCode() {
- int hash = 7;
- hash = 67 * hash + Objects.hashCode(this.subjectCertificate);
- hash = 67 * hash + Objects.hashCode(this.issuerCertificate);
- return hash;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null) {
- return false;
- }
- if (getClass() != obj.getClass()) {
- return false;
- }
- final OcspRequest other = (OcspRequest) obj;
- if (!Objects.equals(this.subjectCertificate,
other.subjectCertificate)) {
- return false;
- }
- if (!Objects.equals(this.issuerCertificate, other.issuerCertificate)) {
- return false;
- }
- return true;
- }
-
- @Override
- public String toString() {
- return "NiFi OCSP Request: " +
- "Subject DN: " + (subjectCertificate != null ?
subjectCertificate.getSubjectX500Principal().getName() : "<null>") +
- " issued by " +
- "Issuer DN: " + (issuerCertificate != null ?
issuerCertificate.getSubjectX500Principal().getName() : "<null>");
- }
-
-}
diff --git
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/ocsp/OcspStatus.java
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/ocsp/OcspStatus.java
deleted file mode 100644
index 563259e72d..0000000000
---
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/ocsp/OcspStatus.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * 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.web.security.x509.ocsp;
-
-/**
- *
- */
-public class OcspStatus {
-
- public enum ResponseStatus {
-
- Successful,
- MalformedRequest,
- InternalError,
- TryLater,
- SignatureRequired,
- Unauthorized,
- Unknown
- }
-
- public enum VerificationStatus {
- Unknown,
- Verified,
- Unverified
- }
-
- public enum ValidationStatus {
- Unknown,
- Good,
- Revoked
- }
-
- private ResponseStatus responseStatus;
- private VerificationStatus verificationStatus;
- private ValidationStatus validationStatus;
-
- public ResponseStatus getResponseStatus() {
- return responseStatus;
- }
-
- public void setResponseStatus(ResponseStatus responseStatus) {
- this.responseStatus = responseStatus;
- }
-
- public VerificationStatus getVerificationStatus() {
- return verificationStatus;
- }
-
- public void setVerificationStatus(VerificationStatus verificationStatus) {
- this.verificationStatus = verificationStatus;
- }
-
- public ValidationStatus getValidationStatus() {
- return validationStatus;
- }
-
- public void setValidationStatus(ValidationStatus validationStatus) {
- this.validationStatus = validationStatus;
- }
-
- @Override
- public String toString() {
- return String.format("Request (%s) Verification (%s) Validation (%s)",
responseStatus, verificationStatus, validationStatus);
- }
-
-}
diff --git
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/cookie/StandardApplicationCookieServiceTest.java
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/cookie/StandardApplicationCookieServiceTest.java
index b4261c000e..6965792173 100644
---
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/cookie/StandardApplicationCookieServiceTest.java
+++
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/cookie/StandardApplicationCookieServiceTest.java
@@ -29,7 +29,6 @@ import org.springframework.mock.web.MockCookie;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
-import jakarta.ws.rs.core.HttpHeaders;
import java.net.URI;
import java.util.Optional;
import java.util.UUID;
@@ -63,6 +62,8 @@ public class StandardApplicationCookieServiceTest {
private static final String COOKIE_VALUE = UUID.randomUUID().toString();
+ private static final String SET_COOKIE_HEADER = "Set-Cookie";
+
private static final ApplicationCookieName COOKIE_NAME =
ApplicationCookieName.LOGOUT_REQUEST_IDENTIFIER;
private URI resourceUri;
@@ -91,7 +92,7 @@ public class StandardApplicationCookieServiceTest {
public void testAddCookie() {
service.addCookie(resourceUri, response, COOKIE_NAME, COOKIE_VALUE);
- verify(response).addHeader(eq(HttpHeaders.SET_COOKIE),
cookieArgumentCaptor.capture());
+ verify(response).addHeader(eq(SET_COOKIE_HEADER),
cookieArgumentCaptor.capture());
final String setCookieHeader = cookieArgumentCaptor.getValue();
assertAddCookieMatches(setCookieHeader, ROOT_PATH, EXPECTED_MAX_AGE);
}
@@ -100,7 +101,7 @@ public class StandardApplicationCookieServiceTest {
public void testAddCookieContextPath() {
service.addCookie(contextResourceUri, response, COOKIE_NAME,
COOKIE_VALUE);
- verify(response).addHeader(eq(HttpHeaders.SET_COOKIE),
cookieArgumentCaptor.capture());
+ verify(response).addHeader(eq(SET_COOKIE_HEADER),
cookieArgumentCaptor.capture());
final String setCookieHeader = cookieArgumentCaptor.getValue();
assertAddCookieMatches(setCookieHeader, CONTEXT_PATH,
EXPECTED_MAX_AGE);
}
@@ -109,7 +110,7 @@ public class StandardApplicationCookieServiceTest {
public void testAddSessionCookie() {
service.addSessionCookie(resourceUri, response, COOKIE_NAME,
COOKIE_VALUE);
- verify(response).addHeader(eq(HttpHeaders.SET_COOKIE),
cookieArgumentCaptor.capture());
+ verify(response).addHeader(eq(SET_COOKIE_HEADER),
cookieArgumentCaptor.capture());
final String setCookieHeader = cookieArgumentCaptor.getValue();
assertAddCookieMatches(setCookieHeader, ROOT_PATH, SESSION_MAX_AGE);
@@ -119,7 +120,7 @@ public class StandardApplicationCookieServiceTest {
public void testAddSessionCookieContextPath() {
service.addSessionCookie(contextResourceUri, response, COOKIE_NAME,
COOKIE_VALUE);
- verify(response).addHeader(eq(HttpHeaders.SET_COOKIE),
cookieArgumentCaptor.capture());
+ verify(response).addHeader(eq(SET_COOKIE_HEADER),
cookieArgumentCaptor.capture());
final String setCookieHeader = cookieArgumentCaptor.getValue();
assertAddCookieMatches(setCookieHeader, CONTEXT_PATH, SESSION_MAX_AGE);
@@ -144,7 +145,7 @@ public class StandardApplicationCookieServiceTest {
public void testRemoveCookie() {
service.removeCookie(resourceUri, response, COOKIE_NAME);
- verify(response).addHeader(eq(HttpHeaders.SET_COOKIE),
cookieArgumentCaptor.capture());
+ verify(response).addHeader(eq(SET_COOKIE_HEADER),
cookieArgumentCaptor.capture());
final String setCookieHeader = cookieArgumentCaptor.getValue();
assertRemoveCookieMatches(setCookieHeader, ROOT_PATH);
}
@@ -153,7 +154,7 @@ public class StandardApplicationCookieServiceTest {
public void testRemoveCookieContextPath() {
service.removeCookie(contextResourceUri, response, COOKIE_NAME);
- verify(response).addHeader(eq(HttpHeaders.SET_COOKIE),
cookieArgumentCaptor.capture());
+ verify(response).addHeader(eq(SET_COOKIE_HEADER),
cookieArgumentCaptor.capture());
final String setCookieHeader = cookieArgumentCaptor.getValue();
assertRemoveCookieMatches(setCookieHeader, CONTEXT_PATH);
}
diff --git
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/saml2/registration/StandardRegistrationBuilderProviderTest.java
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/saml2/registration/StandardRegistrationBuilderProviderTest.java
index 5cd5532a85..165963656c 100644
---
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/saml2/registration/StandardRegistrationBuilderProviderTest.java
+++
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/saml2/registration/StandardRegistrationBuilderProviderTest.java
@@ -19,7 +19,6 @@ package org.apache.nifi.web.security.saml2.registration;
import mockwebserver3.MockResponse;
import mockwebserver3.MockWebServer;
import okhttp3.HttpUrl;
-import org.apache.commons.io.IOUtils;
import org.apache.nifi.security.cert.builder.StandardCertificateBuilder;
import org.apache.nifi.security.ssl.EphemeralKeyStoreBuilder;
import org.apache.nifi.security.ssl.StandardKeyManagerBuilder;
@@ -73,7 +72,7 @@ class StandardRegistrationBuilderProviderTest {
}
@AfterEach
- void shutdownServer() throws IOException {
+ void shutdownServer() {
mockWebServer.close();
}
@@ -182,7 +181,8 @@ class StandardRegistrationBuilderProviderTest {
final String getMetadata() throws IOException {
try (final InputStream inputStream =
Objects.requireNonNull(getClass().getResourceAsStream(METADATA_PATH))) {
- return IOUtils.toString(inputStream, StandardCharsets.UTF_8);
+ final byte[] bytes = inputStream.readAllBytes();
+ return new String(bytes, StandardCharsets.UTF_8);
}
}
diff --git
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/x509/X509AuthenticationProviderTest.java
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/x509/X509AuthenticationProviderTest.java
index d046897a1f..6742f973c7 100644
---
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/x509/X509AuthenticationProviderTest.java
+++
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/x509/X509AuthenticationProviderTest.java
@@ -21,11 +21,9 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import javax.security.auth.x500.X500Principal;
import org.apache.commons.lang3.StringUtils;
-import org.apache.nifi.authentication.AuthenticationResponse;
import org.apache.nifi.authorization.AuthorizationRequest;
import org.apache.nifi.authorization.AuthorizationResult;
import org.apache.nifi.authorization.Authorizer;
@@ -53,7 +51,6 @@ import static org.mockito.Mockito.when;
public class X509AuthenticationProviderTest {
- private static final String INVALID_CERTIFICATE = "invalid-certificate";
private static final String IDENTITY_1 = "CN=identity-1";
private static final String ANONYMOUS = "";
@@ -61,9 +58,9 @@ public class X509AuthenticationProviderTest {
private static final String PROXY_1 = "CN=proxy-1";
private static final String PROXY_2 = "CN=proxy-2";
+ private static final String ISSUER = "CN=issuer";
private X509AuthenticationProvider x509AuthenticationProvider;
- private X509IdentityProvider certificateIdentityProvider;
private SubjectDnX509PrincipalExtractor extractor;
private Authorizer authorizer;
@@ -71,18 +68,6 @@ public class X509AuthenticationProviderTest {
public void setup() {
extractor = new SubjectDnX509PrincipalExtractor();
- certificateIdentityProvider = mock(X509IdentityProvider.class);
-
when(certificateIdentityProvider.authenticate(any(X509Certificate[].class))).then(invocation
-> {
- final X509Certificate[] certChain = invocation.getArgument(0);
- final String identity =
extractor.extractPrincipal(certChain[0]).toString();
-
- if (INVALID_CERTIFICATE.equals(identity)) {
- throw new IllegalArgumentException();
- }
-
- return new AuthenticationResponse(identity, identity,
TimeUnit.MILLISECONDS.convert(12, TimeUnit.HOURS), "");
- });
-
authorizer = mock(Authorizer.class);
when(authorizer.authorize(any(AuthorizationRequest.class))).then(invocation -> {
final AuthorizationRequest request = invocation.getArgument(0);
@@ -94,12 +79,7 @@ public class X509AuthenticationProviderTest {
return AuthorizationResult.approved();
});
- x509AuthenticationProvider = new
X509AuthenticationProvider(certificateIdentityProvider, authorizer,
NiFiProperties.createBasicNiFiProperties(null));
- }
-
- @Test
- public void testInvalidCertificate() {
- assertThrows(InvalidAuthenticationException.class, () ->
x509AuthenticationProvider.authenticate(getX509Request("",
INVALID_CERTIFICATE)));
+ x509AuthenticationProvider = new
X509AuthenticationProvider(authorizer,
NiFiProperties.createBasicNiFiProperties(null));
}
@Test
@@ -136,7 +116,7 @@ public class X509AuthenticationProviderTest {
// override the setting to enable anonymous authentication
final Map<String, String> additionalProperties =
Map.of(NiFiProperties.SECURITY_ANONYMOUS_AUTHENTICATION,
Boolean.TRUE.toString());
final NiFiProperties properties =
NiFiProperties.createBasicNiFiProperties(null, additionalProperties);
- x509AuthenticationProvider = new
X509AuthenticationProvider(certificateIdentityProvider, authorizer, properties);
+ x509AuthenticationProvider = new
X509AuthenticationProvider(authorizer, properties);
final NiFiAuthenticationToken auth = (NiFiAuthenticationToken)
x509AuthenticationProvider.authenticate(getX509Request(buildProxyChain(ANONYMOUS),
PROXY_1));
final NiFiUser user = ((NiFiUserDetails)
auth.getPrincipal()).getNiFiUser();
@@ -185,7 +165,7 @@ public class X509AuthenticationProviderTest {
additionalProperties.put(NiFiProperties.SECURITY_ANONYMOUS_AUTHENTICATION,
Boolean.TRUE.toString());
final NiFiProperties properties =
NiFiProperties.createBasicNiFiProperties(null, additionalProperties);
- x509AuthenticationProvider = new
X509AuthenticationProvider(certificateIdentityProvider, authorizer, properties);
+ x509AuthenticationProvider = new
X509AuthenticationProvider(authorizer, properties);
final NiFiAuthenticationToken auth = (NiFiAuthenticationToken)
x509AuthenticationProvider.authenticate(getX509Request(buildProxyChain(IDENTITY_1,
ANONYMOUS), PROXY_1));
final NiFiUser user = ((NiFiUserDetails)
auth.getPrincipal()).getNiFiUser();
@@ -264,13 +244,9 @@ public class X509AuthenticationProviderTest {
}
private X509AuthenticationRequestToken getX509Request(final String
proxyChain, final String identity) {
- return getX509Request(proxyChain, null, identity);
- }
-
- private X509AuthenticationRequestToken getX509Request(final String
proxyChain, final String proxiedEntityGroups, final String identity) {
return new X509AuthenticationRequestToken(
proxyChain,
- proxiedEntityGroups,
+ null,
extractor,
new X509Certificate[]{getX509Certificate(identity)},
"",
@@ -279,7 +255,8 @@ public class X509AuthenticationProviderTest {
private X509Certificate getX509Certificate(final String identity) {
final X509Certificate certificate = mock(X509Certificate.class);
- when(certificate.getSubjectX500Principal()).then(invocation -> new
X500Principal(identity));
+ when(certificate.getSubjectX500Principal()).thenReturn(new
X500Principal(identity));
+ when(certificate.getIssuerX500Principal()).thenReturn(new
X500Principal(ISSUER));
return certificate;
}
}
\ No newline at end of file
diff --git
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/x509/ocsp/OcspCertificateValidatorTest.java
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/x509/ocsp/OcspCertificateValidatorTest.java
deleted file mode 100644
index 215e5c1c1f..0000000000
---
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/x509/ocsp/OcspCertificateValidatorTest.java
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * 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.web.security.x509.ocsp;
-
-import java.io.IOException;
-import java.math.BigInteger;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.SignatureException;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import org.bouncycastle.asn1.x500.X500Name;
-import org.bouncycastle.asn1.x509.ExtendedKeyUsage;
-import org.bouncycastle.asn1.x509.Extension;
-import org.bouncycastle.asn1.x509.KeyPurposeId;
-import org.bouncycastle.asn1.x509.KeyUsage;
-import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
-import org.bouncycastle.cert.X509CertificateHolder;
-import org.bouncycastle.cert.X509v3CertificateBuilder;
-import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
-import org.bouncycastle.operator.ContentSigner;
-import org.bouncycastle.operator.OperatorCreationException;
-import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
-import org.junit.jupiter.api.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-
-public class OcspCertificateValidatorTest {
- private static final Logger logger =
LoggerFactory.getLogger(OcspCertificateValidatorTest.class);
-
- private static final int KEY_SIZE = 2048;
-
- private static final long YESTERDAY = System.currentTimeMillis() - 24 * 60
* 60 * 1000;
- private static final long ONE_YEAR_FROM_NOW = System.currentTimeMillis() +
365L * 24 * 60 * 60 * 1000;
- private static final String SIGNATURE_ALGORITHM = "SHA256withRSA";
-
- /**
- * Generates a public/private RSA keypair using the default key size.
- *
- * @return the keypair
- * @throws NoSuchAlgorithmException if the RSA algorithm is not available
- */
- private static KeyPair generateKeyPair() throws NoSuchAlgorithmException {
- KeyPairGenerator keyPairGenerator =
KeyPairGenerator.getInstance("RSA");
- keyPairGenerator.initialize(KEY_SIZE);
- return keyPairGenerator.generateKeyPair();
- }
-
- /**
- * Generates a signed certificate using an on-demand keypair.
- *
- * @param dn the DN
- * @return the certificate
- * @throws IOException if an exception occurs
- * @throws NoSuchAlgorithmException if an exception occurs
- * @throws CertificateException if an exception occurs
- * @throws OperatorCreationException if an exception occurs
- */
- private static X509Certificate generateCertificate(String dn) throws
IOException, NoSuchAlgorithmException, CertificateException,
- OperatorCreationException {
- KeyPair keyPair = generateKeyPair();
- return generateCertificate(dn, keyPair);
- }
-
- /**
- * Generates a signed certificate with a specific keypair.
- *
- * @param dn the DN
- * @param keyPair the public key will be included in the certificate and
the the private key is used to sign the certificate
- * @return the certificate
- * @throws IOException if an exception occurs
- * @throws CertificateException if an exception occurs
- * @throws OperatorCreationException if an exception occurs
- */
- private static X509Certificate generateCertificate(String dn, KeyPair
keyPair) throws IOException, CertificateException,
- OperatorCreationException {
- PrivateKey privateKey = keyPair.getPrivate();
- ContentSigner sigGen = new
JcaContentSignerBuilder(SIGNATURE_ALGORITHM).build(privateKey);
- SubjectPublicKeyInfo subPubKeyInfo =
SubjectPublicKeyInfo.getInstance(keyPair.getPublic().getEncoded());
- Date startDate = new Date(YESTERDAY);
- Date endDate = new Date(ONE_YEAR_FROM_NOW);
-
- X509v3CertificateBuilder certBuilder = new X509v3CertificateBuilder(
- new X500Name(dn),
- BigInteger.valueOf(System.currentTimeMillis()),
- startDate, endDate,
- new X500Name(dn),
- subPubKeyInfo);
-
- // Set certificate extensions
- // (1) digitalSignature extension
- certBuilder.addExtension(Extension.keyUsage, true,
- new KeyUsage(KeyUsage.digitalSignature |
KeyUsage.keyEncipherment | KeyUsage.dataEncipherment | KeyUsage.keyAgreement));
-
- // (2) extendedKeyUsage extension
- final List<KeyPurposeId> ekUsages = new ArrayList<>();
- ekUsages.add(KeyPurposeId.id_kp_clientAuth);
- ekUsages.add(KeyPurposeId.id_kp_serverAuth);
- certBuilder.addExtension(Extension.extendedKeyUsage, false, new
ExtendedKeyUsage(ekUsages.toArray(new KeyPurposeId[0])));
-
- // Sign the certificate
- X509CertificateHolder certificateHolder = certBuilder.build(sigGen);
- return new
JcaX509CertificateConverter().getCertificate(certificateHolder);
- }
-
- /**
- * Generates a certificate signed by the issuer key.
- *
- * @param dn the subject DN
- * @param issuerDn the issuer DN
- * @param issuerKey the issuer private key
- * @return the certificate
- * @throws NoSuchAlgorithmException if an exception occurs
- * @throws CertificateException if an exception occurs
- * @throws OperatorCreationException if an exception occurs
- */
- private static X509Certificate generateIssuedCertificate(String dn, String
issuerDn, PrivateKey issuerKey) throws NoSuchAlgorithmException,
CertificateException,
- OperatorCreationException {
- KeyPair keyPair = generateKeyPair();
- return generateIssuedCertificate(dn, keyPair.getPublic(), issuerDn,
issuerKey);
- }
-
- /**
- * Generates a certificate with a specific public key signed by the issuer
key.
- *
- * @param dn the subject DN
- * @param publicKey the subject public key
- * @param issuerDn the issuer DN
- * @param issuerKey the issuer private key
- * @return the certificate
- * @throws CertificateException if an exception occurs
- * @throws OperatorCreationException if an exception occurs
- */
- private static X509Certificate generateIssuedCertificate(String dn,
PublicKey publicKey, String issuerDn, PrivateKey issuerKey) throws
- CertificateException, OperatorCreationException {
- ContentSigner sigGen = new
JcaContentSignerBuilder(SIGNATURE_ALGORITHM).build(issuerKey);
- SubjectPublicKeyInfo subPubKeyInfo =
SubjectPublicKeyInfo.getInstance(publicKey.getEncoded());
- Date startDate = new Date(YESTERDAY);
- Date endDate = new Date(ONE_YEAR_FROM_NOW);
-
- X509v3CertificateBuilder v3CertGen = new X509v3CertificateBuilder(
- new X500Name(issuerDn),
- BigInteger.valueOf(System.currentTimeMillis()),
- startDate, endDate,
- new X500Name(dn),
- subPubKeyInfo);
-
- X509CertificateHolder certificateHolder = v3CertGen.build(sigGen);
- return new
JcaX509CertificateConverter().getCertificate(certificateHolder);
- }
-
- @Test
- public void testShouldGenerateCertificate() throws Exception {
- // Arrange
- final String testDn = "CN=This is a test";
-
- // Act
- X509Certificate certificate = generateCertificate(testDn);
- logger.info("Generated certificate: \n{}", certificate);
-
- // Assert
- assertEquals(testDn, certificate.getSubjectX500Principal().getName());
- assertEquals(testDn, certificate.getIssuerX500Principal().getName());
- certificate.verify(certificate.getPublicKey());
- }
-
- @Test
- public void testShouldGenerateCertificateFromKeyPair() throws Exception {
- // Arrange
- final String testDn = "CN=This is a test";
- final KeyPair keyPair = generateKeyPair();
-
- // Act
- X509Certificate certificate = generateCertificate(testDn, keyPair);
- logger.info("Generated certificate: \n{}", certificate);
-
- // Assert
- assertEquals(keyPair.getPublic(), certificate.getPublicKey());
- assertEquals(testDn, certificate.getSubjectX500Principal().getName());
- assertEquals(testDn, certificate.getIssuerX500Principal().getName());
- certificate.verify(certificate.getPublicKey());
- }
-
- @Test
- public void testShouldGenerateIssuedCertificate() throws Exception {
- // Arrange
- final String testDn = "CN=This is a signed test";
- final String issuerDn = "CN=Issuer CA";
- final KeyPair issuerKeyPair = generateKeyPair();
- final PrivateKey issuerPrivateKey = issuerKeyPair.getPrivate();
-
- final X509Certificate issuerCertificate =
generateCertificate(issuerDn, issuerKeyPair);
- logger.info("Generated issuer certificate: \n{}", issuerCertificate);
-
- // Act
- X509Certificate certificate = generateIssuedCertificate(testDn,
issuerDn, issuerPrivateKey);
- logger.info("Generated signed certificate: \n{}", certificate);
-
- // Assert
- assertEquals(issuerKeyPair.getPublic(),
issuerCertificate.getPublicKey());
- assertEquals(testDn, certificate.getSubjectX500Principal().getName());
- assertEquals(issuerDn, certificate.getIssuerX500Principal().getName());
- certificate.verify(issuerCertificate.getPublicKey());
-
- assertThrows(SignatureException.class, () ->
certificate.verify(certificate.getPublicKey()));
- }
-}
\ No newline at end of file
diff --git
a/nifi-system-tests/nifi-system-test-suite/src/test/resources/conf/clustered/node1/nifi.properties
b/nifi-system-tests/nifi-system-test-suite/src/test/resources/conf/clustered/node1/nifi.properties
index 7f6fc82802..0083410bb9 100644
---
a/nifi-system-tests/nifi-system-test-suite/src/test/resources/conf/clustered/node1/nifi.properties
+++
b/nifi-system-tests/nifi-system-test-suite/src/test/resources/conf/clustered/node1/nifi.properties
@@ -164,8 +164,6 @@ nifi.security.truststoreType=PKCS12
nifi.security.truststorePasswd=
nifi.security.user.authorizer=system-test-authorizer
nifi.security.user.login.identity.provider=
-nifi.security.ocsp.responder.url=
-nifi.security.ocsp.responder.certificate=
# OpenId Connect SSO Properties #
nifi.security.user.oidc.discovery.url=
diff --git
a/nifi-system-tests/nifi-system-test-suite/src/test/resources/conf/clustered/node2/nifi.properties
b/nifi-system-tests/nifi-system-test-suite/src/test/resources/conf/clustered/node2/nifi.properties
index 6b3df6197d..843bd4b884 100644
---
a/nifi-system-tests/nifi-system-test-suite/src/test/resources/conf/clustered/node2/nifi.properties
+++
b/nifi-system-tests/nifi-system-test-suite/src/test/resources/conf/clustered/node2/nifi.properties
@@ -164,8 +164,6 @@ nifi.security.truststoreType=PKCS12
nifi.security.truststorePasswd=
nifi.security.user.authorizer=system-test-authorizer
nifi.security.user.login.identity.provider=
-nifi.security.ocsp.responder.url=
-nifi.security.ocsp.responder.certificate=
# OpenId Connect SSO Properties #
nifi.security.user.oidc.discovery.url=
diff --git
a/nifi-system-tests/nifi-system-test-suite/src/test/resources/conf/default/nifi.properties
b/nifi-system-tests/nifi-system-test-suite/src/test/resources/conf/default/nifi.properties
index 5bfb6ebca3..a74f60723f 100644
---
a/nifi-system-tests/nifi-system-test-suite/src/test/resources/conf/default/nifi.properties
+++
b/nifi-system-tests/nifi-system-test-suite/src/test/resources/conf/default/nifi.properties
@@ -165,8 +165,6 @@ nifi.security.truststoreType=PKCS12
nifi.security.truststorePasswd=
nifi.security.user.authorizer=system-test-authorizer
nifi.security.user.login.identity.provider=
-nifi.security.ocsp.responder.url=
-nifi.security.ocsp.responder.certificate=
# OpenId Connect SSO Properties #
nifi.security.user.oidc.discovery.url=
diff --git
a/nifi-system-tests/nifi-system-test-suite/src/test/resources/conf/pythonic/nifi.properties
b/nifi-system-tests/nifi-system-test-suite/src/test/resources/conf/pythonic/nifi.properties
index a0199e7c12..779354310b 100644
---
a/nifi-system-tests/nifi-system-test-suite/src/test/resources/conf/pythonic/nifi.properties
+++
b/nifi-system-tests/nifi-system-test-suite/src/test/resources/conf/pythonic/nifi.properties
@@ -169,8 +169,6 @@ nifi.security.truststoreType=PKCS12
nifi.security.truststorePasswd=
nifi.security.user.authorizer=system-test-authorizer
nifi.security.user.login.identity.provider=
-nifi.security.ocsp.responder.url=
-nifi.security.ocsp.responder.certificate=
# OpenId Connect SSO Properties #
nifi.security.user.oidc.discovery.url=