Support Questions

Find answers, ask questions, and share your expertise

About NiFi Registry LDAP Configuration

avatar
Explorer

Hello,

I have a 3-node NiFi cluster, and I want to manage it using NiFi Registry. I configured both NiFi and NiFi Registry with a single certificate using the TLS Toolkit. I also set up LDAP integration. I can successfully connect to both NiFi and NiFi Registry individually using my LDAP users.

However, the LDAP user that I added and authorized in the Registry does not appear in NiFi. With the certificate user, I can view the bucket in NiFi Registry from NiFi and perform flow version control. But I cannot do this with my LDAP user.

NOTE: Even if I generate separate certificates for NiFi and NiFi Registry and trust each certificate independently, the certificate user does not have permission to view the bucket. This is because the certificate user from the Registry is also not created in NiFi. For this reason, I generated both from the same certificate.

Nifi / Nifi Registry version: 1.28.1

Nifi Registry nifi-registry.properties

# 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.

# web properties #
nifi.registry.web.war.directory=./lib
nifi.registry.web.http.host=
nifi.registry.web.http.port=
nifi.registry.web.https.host=vtmnosqlnifip04.yyy.com
nifi.registry.web.https.port=18084
nifi.registry.web.https.application.protocols=http/1.1
nifi.registry.web.jetty.working.directory=./work/jetty
nifi.registry.web.jetty.threads=200
nifi.registry.web.should.send.server.version=true

# security properties #
nifi.registry.security.keystore=/data/certs/keystore.jks
nifi.registry.security.keystoreType=jks
nifi.registry.security.keystorePasswd=PBSckF3zHJj8h7iAsZqes2zJhXyzjXVanE0F8Cy4NEA
nifi.registry.security.keyPasswd=PBSckF3zHJj8h7iAsZqes2zJhXyzjXVanE0F8Cy4NEA
nifi.registry.security.truststore=/data/certs/truststore.jks
nifi.registry.security.truststoreType=jks
nifi.registry.security.truststorePasswd=rFXj+NsPyiH1tf43/sD6NCYW9mdXI9hZs+T/8DHs8b4
nifi.registry.security.needClientAuth=false
nifi.registry.security.authorizers.configuration.file=./conf/authorizers.xml
nifi.registry.security.authorizer=managed-authorizer
nifi.registry.security.identity.providers.configuration.file=./conf/identity-providers.xml
nifi.registry.security.identity.provider=ldap-identity-provider

# sensitive property protection properties #
# nifi.registry.sensitive.props.additional.keys=

# providers properties #
nifi.registry.providers.configuration.file=./conf/providers.xml

# registry alias properties #
nifi.registry.registry.alias.configuration.file=./conf/registry-aliases.xml

# extensions working dir #
nifi.registry.extensions.working.directory=./work/extensions

# legacy database properties, used to migrate data from original DB to new DB below
# NOTE: Users upgrading from 0.1.0 should leave these populated, but new installs after 0.1.0 should leave these empty
nifi.registry.db.directory=
nifi.registry.db.url.append=

# database properties
nifi.registry.db.url=jdbc:h2:./database/nifi-registry-primary;AUTOCOMMIT=OFF;DB_CLOSE_ON_EXIT=FALSE;LOCK_MODE=3;LOCK_TIMEOUT=25000;WRITE_DELAY=0;AUTO_SERVER=FALSE
nifi.registry.db.driver.class=org.h2.Driver
nifi.registry.db.driver.directory=
nifi.registry.db.username=nifireg
nifi.registry.db.password=nifireg
nifi.registry.db.maxConnections=5
nifi.registry.db.sql.debug=false

# extension directories #
# Each property beginning with "nifi.registry.extension.dir." will be treated as location for an extension,
# and a class loader will be created for each location, with the system class loader as the parent
#
#nifi.registry.extension.dir.1=/path/to/extension1
#nifi.registry.extension.dir.2=/path/to/extension2

nifi.registry.extension.dir.aws=./ext/aws/lib

# Identity Mapping Properties #
# These properties allow normalizing user identities such that identities coming from different identity providers
# (certificates, LDAP, Kerberos) can be treated the same internally in NiFi. The following example demonstrates normalizing
# DNs from certificates and principals from Kerberos into a common identity string:
#
# nifi.registry.security.identity.mapping.pattern.dn=^CN=(.*?), OU=(.*?), O=(.*?), L=(.*?), ST=(.*?), C=(.*?)$
# nifi.registry.security.identity.mapping.value.dn=$1@$2
# nifi.registry.security.identity.mapping.transform.dn=NONE

# nifi.registry.security.identity.mapping.pattern.kerb=^(.*?)/instance@(.*?)$
# nifi.registry.security.identity.mapping.value.kerb=$1@$2
# nifi.registry.security.identity.mapping.transform.kerb=UPPER

# Group Mapping Properties #
# These properties allow normalizing group names coming from external sources like LDAP. The following example
# lowercases any group name.
#
# nifi.registry.security.group.mapping.pattern.anygroup=^(.*)$
# nifi.registry.security.group.mapping.value.anygroup=$1
# nifi.registry.security.group.mapping.transform.anygroup=LOWER


# kerberos properties #
#nifi.registry.kerberos.krb5.file=
#nifi.registry.kerberos.spnego.principal=
#nifi.registry.kerberos.spnego.keytab.location=
#nifi.registry.kerberos.spnego.authentication.expiration=12 hours

# OIDC #
#nifi.registry.security.user.oidc.discovery.url=
#nifi.registry.security.user.oidc.connect.timeout=
#nifi.registry.security.user.oidc.read.timeout=
#nifi.registry.security.user.oidc.client.id=
#nifi.registry.security.user.oidc.client.secret=
#nifi.registry.security.user.oidc.preferred.jwsalgorithm=

# revision management #
# This feature should remain disabled until a future NiFi release that supports the revision API changes
nifi.registry.revisions.enabled=false

 

Nifi Registry authorizers.xml

<authorizers>
    <userGroupProvider>
        <identifier>file-user-group-provider</identifier>
        <class>org.apache.nifi.registry.security.authorization.file.FileUserGroupProvider</class>
        <property name="Users File">./conf/users.xml</property>
        <property name="Initial User Identity 1">CN=nifi_amadeus_admin</property>
        <property name="Initial User Identity 2">CN=vtmnosqlnifip04.yyy.com, OU=NIFI</property>
        <property name="Initial User Identity 3">CN=vtmnosqlnifip03.yyy.com, OU=NIFI</property>
        <property name="Initial User Identity 4">CN=vtmnosqlnifip02.yyy.com, OU=NIFI</property>
        <property name="Initial User Identity 5">CN=vtmnosqlnifip01.yyy.com, OU=NIFI</property>
    </userGroupProvider>
 
    <accessPolicyProvider>
        <identifier>file-access-policy-provider</identifier>
        <class>org.apache.nifi.registry.security.authorization.file.FileAccessPolicyProvider</class>
        <property name="User Group Provider">file-user-group-provider</property>
        <property name="Authorizations File">./conf/authorizations.xml</property>
       <property name="Initial Admin Identity">CN=nifi_amadeus_admin</property>
        <property name="Node Identity 1">CN=vtmnosqlnifip04.yyy.com, OU=NIFI</property>
        <property name="NiFi Group Name"></property>
        <property name="NiFi Identity 1">CN=vtmnosqlnifip01.yyy.com, OU=NIFI</property>
       <property name="NiFi Identity 2">CN=vtmnosqlnifip02.yyy.com, OU=NIFI</property>
        <property name="NiFi Identity 3">CN=vtmnosqlnifip03.yyy.com, OU=NIFI</property>
    </accessPolicyProvider>
 
    <authorizer>
        <identifier>managed-authorizer</identifier>
        <class>org.apache.nifi.registry.security.authorization.StandardManagedAuthorizer</class>
        <property name="Access Policy Provider">file-access-policy-provider</property>
    </authorizer>
 
</authorizers>

Nifi Registry identity-providers.xml

<identityProviders>
 
    <provider>
        <identifier>ldap-identity-provider</identifier>
        <class>org.apache.nifi.registry.security.ldap.LdapIdentityProvider</class>
        <property name="Authentication Strategy">SIMPLE</property>
 
        <property name="Manager DN">CN=service_user,CN=Users,DC=xxx,DC=yyy,DC=com</property>
        <property name="Manager Password">OPGwqvD8YrHi</property>
        
        <property name="Referral Strategy">FOLLOW</property>
        <property name="Connect Timeout">10 secs</property>
        <property name="Read Timeout">10 secs</property>
 
        <property name="TLS - Keystore">/data/certs/keystore.jks</property>
    <property name="TLS - Keystore Password">PBSckF3zHJj8h7iAsZqes2zJhXyzjXVanE0F8Cy4NEA</property>
        <property name="TLS - Keystore Type">JKS</property>
        <property name="TLS - Truststore">/data/certs/truststore.jks</property>
    <property name="TLS - Truststore Password">rFXj+NsPyiH1tf43/sD6NCYW9mdXI9hZs+T/8DHs8b4</property>
        <property name="TLS - Truststore Type">JKS</property>
        <property name="TLS - Client Auth">NONE</property>
    <property name="TLS - Protocol">TLS</property>
    <property name="TLS - Shutdown Gracefully">true</property>
 
    <property name="Url">ldaps://ldap.xxx.yyy.com:636</property>
        <property name="User Search Base">CN=Users,DC=xxx,DC=yyy,DC=com</property>
    <property name="User Search Filter">(&amp;(objectClass=user)(sAMAccountName={0}))</property>
 
        <property name="Identity Strategy">USE_USERNAME</property>
        <property name="Authentication Expiration">12 hours</property>
    </provider>

I would appreciate your assistance on this matter.

 

1 REPLY 1

avatar
Master Mentor

@melek6199 

Let me try to address each of your statements as there appears to be some misunderstanding of how authentication and authorization works between NiFi and NiFi-Registry.

I have a 3-node NiFi cluster, and I want to manage it using NiFi Registry. I configured both NiFi and NiFi Registry with a single certificate using the TLS Toolkit. I also set up LDAP integration. I can successfully connect to both NiFi and NiFi Registry individually using my LDAP users.
  • NiFi-Registry does not manage your NiFi cluster.  These are two different services.  NiFi-Registry is used by NiFi to version control process groups created and managed in NiFi.  
  • It is not a security best practice to use one certificate for all your servers.  You should have one certificate per server.  If you have two services (A NiFi node and NiFi-Registry on the same server, they would both use the same certificate).  In production I would recommend using certificates signed by actual legitimate signing authorities versus TLS toolkit generated certificates and truststore)
    • Your keystores must meet the following requirements:
      • Contain only one PrivateKey Entry
      • That PrivateKey entry supports both ClientAuth and ServerAuth ExtendedKeyUsage (EKU). (Note: NiFi-Registry does not require ClientAuth, but no harm in having it)
      • Contains at least one SAN entry that matches the server's hostname on which the certificate is being used. 
    • Your NiFi/NiFi-Registry Truststore must meet following requirements:
      • Contain a TrustedCertEntry for every signer/issuer of the certificates passed in a mutualTLS handshake (The compete trustchain for every certificate that will be used to communicate between NiFi node and with NiFi-Registry).
      • You can use the NiFi TLS toolkit to generate 4 keystores and 1 truststore you can use with your NiFi and NiFi-Registry services, but make sure you are running with the "--subjectAlternativeNames" option.  Those SAN should include the hostnames of the servers on which the services will run. (Now technically you could create one certificate with SANs for all the hosts and then use that one cert on all hosts, but as I said, not a security best practice).

 

However, the LDAP user that I added and authorized in the Registry does not appear in NiFi. With the certificate user, I can view the bucket in NiFi Registry from NiFi and perform flow version control. But I cannot do this with my LDAP user.
  • The user that authenticates into NiFi-Registry does not need to exist in NiFi; however, any authenticated user identity authenticated into NiFi must exist and have proper authorization in NiFi-Registry in order to conduct version control operation within NiFi.
  • When you ldap-user authenticates into NiFi you will see that user's "user identity" displayed in the upper right corner (Keep in mind that your user is only authenticated into the NiFi node you access the cluster from and not all the NiFi nodes).  When that user attempts to start version control on a process group, NiFi connects and authenticates with NiFi-Registry via a MutualTLS exchange/handshake. In that connection it will proxy the request on behalf of that "user identity" (case sensitive).  This means that not only do the NiFi node clientAuth certificates need to be authorized in NiFi-Registry to read on "Can Manage Buckets " and read,write,delete on "Can Proxy Requests", the NiFi "user identity" need to be authorized on any bucket you want that "user identity" to be able to use for version control.  (let me know if you need help with how a mutualTLS handshake works)
  • Since your NiFi authenticated ldap "user-identity" has not been added and authorized in NiFi-Registry on any buckets, nothing will appear in the list of available buckets for that "user-identity" in NiFi.

 

NOTE: Even if I generate separate certificates for NiFi and NiFi Registry and trust each certificate independently, the certificate user does not have permission to view the bucket. This is because the certificate user from the Registry is also not created in NiFi. For this reason, I generated both from the same certificate.
  • From what i shared in response to two section above, you can see that the certificates used by the NiFi host are only used to proxy requests to NiFi-Registry on behalf of the "user identity" authenticated with NiFi.

There are few things that don't make sense to me in your shared NiFi-Registry configuration:

 NiFi-Registry identity-providers.xml:

  • I see you set " <property name="Authentication Strategy">SIMPLE</property>", yet your ldap URL is "ldaps".  This should then also be set to "LDAPS".

NiFi-Registry authorizers.xml:

  • You are using the file-user-group-provider which allows you to manually define an initial set of "user identities" on first startup (node edits after to this config will happen if the users.xml already exists during startup).  This provider also allows for the adding of additional "user identities" later via the NiFi-Registry UI directly.
  • NOTE: There is also an available ldap-user-group-provider that can be used to sync select users "user identity" and groups "group-identity" from ldap into your NiFi-Registry list of identities.  This is helpful if you don;t want to manage your ldap user and group identities manually within NiFi and NIFi-Registry.
  • You are the file-access-policy provider which only created the authorizations.xml file if it does not already exist on startup. In it I can see "Initial Admin Identity">CN=nifi_amadeus_admin  is set; however, in your ldap-provider you have configured "Identity Strategy">USE_USERNAME. I can only assume you did similar in your NiFi setup? It is unlikely that when you are logging into your NiFi you are typing the username as "CN=nifi_amadeua_admin" since this would not be the expected value in the "sAMAccountName" ldap field/attribute.  That means your initial admin "user identity" does not match the identity of your authenticated user (unless you have this set because you are using the a certificate to auth in to the services with the above).

In the end, there are the following key things that need to know:

  1. user-identities must match and are case sensitive.  ("Bob" and "bob" would be treated as two unique user identities.  So the user identity as displayed in upper right corner in NiFi UI must be authorized on specific bucket(s) in NiFi-Registry in order to successfully use  version control in NIFi.  This you do not have setup correctly yet. 
  2. NiFi nodes also need to be properly authorized in NiFi-Registry for mange buckets and all proxy permissions.  The node's user identity is comes from the NiFi node's clientAuth certificate full DN.  That full DN can be modified through the use of the identity.mapping properties in the NiFi-Registry.properties file. Note: In your shared NiFi-Registry.properties file the identity.mapping properties are commented out are not in use, so full DN of NiFi node would be used as node's user identity and need to be authorized which corresponds to with full DN used in the file-access-policy provider you have configured.

I know above is a lot of information, but wanted you to fully understand how the authentication  and authorization between NiFi and NiFi-Registry works.

Please help our community grow. If you found any of the suggestions/solutions provided helped you with solving your issue or answering your question, please take a moment to login and click "Accept as Solution" on one or more of them that helped.

Thank you,
Matt