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 55b9f980b3 NIFI-15000 Removed AzureGraphUserGroupProvider
55b9f980b3 is described below
commit 55b9f980b34e50c7efe9d576fcdbdb0e4b27f62a
Author: exceptionfactory <[email protected]>
AuthorDate: Mon Sep 22 14:18:50 2025 -0500
NIFI-15000 Removed AzureGraphUserGroupProvider
- Removed license and notice sections no longer applicable from azure-nar
Signed-off-by: Pierre Villard <[email protected]>
This closes #10335.
---
nifi-code-coverage/pom.xml | 5 -
.../src/main/asciidoc/administration-guide.adoc | 36 --
.../nifi-azure-graph-authorizer/pom.xml | 57 ---
.../azure/AzureGraphUserGroupProvider.java | 451 ---------------------
.../azure/ClientCredentialAuthProvider.java | 191 ---------
.../azure/ImmutableAzureGraphUserGroup.java | 156 -------
...org.apache.nifi.authorization.UserGroupProvider | 15 -
.../nifi-azure-bundle/nifi-azure-nar/pom.xml | 12 -
.../src/main/resources/META-INF/LICENSE | 118 ------
.../src/main/resources/META-INF/NOTICE | 98 -----
nifi-extension-bundles/nifi-azure-bundle/pom.xml | 3 +-
.../src/main/resources/conf/authorizers.xml | 44 --
12 files changed, 1 insertion(+), 1185 deletions(-)
diff --git a/nifi-code-coverage/pom.xml b/nifi-code-coverage/pom.xml
index d9c9177042..e0c98d025a 100644
--- a/nifi-code-coverage/pom.xml
+++ b/nifi-code-coverage/pom.xml
@@ -679,11 +679,6 @@
<artifactId>nifi-aws-service-api</artifactId>
<version>2.7.0-SNAPSHOT</version>
</dependency>
- <dependency>
- <groupId>org.apache.nifi</groupId>
- <artifactId>nifi-azure-graph-authorizer</artifactId>
- <version>2.7.0-SNAPSHOT</version>
- </dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-azure-parameter-providers</artifactId>
diff --git a/nifi-docs/src/main/asciidoc/administration-guide.adoc
b/nifi-docs/src/main/asciidoc/administration-guide.adoc
index c41e6d735e..1168d57314 100644
--- a/nifi-docs/src/main/asciidoc/administration-guide.adoc
+++ b/nifi-docs/src/main/asciidoc/administration-guide.adoc
@@ -867,42 +867,6 @@ The LdapUserGroupProvider has the following properties:
NOTE: Any identity mapping rules specified in _nifi.properties_ will also be
applied to the user identities. Group names are not mapped.
-==== AzureGraphUserGroupProvider
-
-The AzureGraphUserGroupProvider fetches users and groups from Azure Active
Directory (AAD) using the Microsoft Graph API.
-
-A subset of groups are fetched based on filter conditions (`Group Filter
Prefix`, `Group Filter Suffix`, `Group Filter Substring`, and `Group Filter
List Inclusion`) evaluated against the _displayName_ property of the Azure AD
group. Member users are then loaded from these groups. At least one filter
condition should be specified.
-
-This provider requires an Azure app registration with:
-
-* Microsoft Graph Group.Read.All and User.Read.All API permissions with admin
consent
-* A client secret or application password
-* ID token claims for upn and/or email
-
-See link:https://docs.microsoft.com/en-us/graph/auth-v2-service[here^] and
link:https://docs.microsoft.com/en-us/azure/active-directory/develop/scenario-daemon-app-registration[here^]
for more information on how to create a valid app registration.
-
-The AzureGraphUserGroupProvider has the following properties:
-
-[options="header,footer"]
-|==================================================================================================================================================
-| Property Name | Description
-|`Refresh Delay` | Duration of delay between each user and group refresh.
Default is `5 mins`.
-|`Authority Endpoint` | The endpoint of the Azure AD login. This can be found
in the Azure portal under Azure Active Directory -> App registrations ->
[application name] -> Endpoints. For example, the global authority endpoint is
`https://login.microsoftonline.com`.
-|`Graph Endpoint` | The endpoint of the Azure Graph API, with the version
identifier attached. The base url can be found in the Azure portal under Azure
Active Directory -> App registrations -> [application name] -> Endpoints. For
example, the global graph endpoint is `https://graph.microsoft.com/v1.0`, which
is also the default setting.
-|`Graph Scope` | The url for the Graph api scope. See
https://learn.microsoft.com/en-us/azure/active-directory/develop/scopes-oidc
for an explanation of scopes. This usually only needs to be changed if you are
connecting to a different `Graph Endpoint`. The Azure global default scope is
`https://graph.microsoft.com/.default`, which is also the default setting.
-|`Directory ID` | Tenant ID or Directory ID of the Azure AD tenant. This can
be found in the Azure portal under Azure Active Directory -> App registrations
-> [application name] -> Directory (tenant) ID.
-|`Application ID` | Client ID or Application ID of the Azure app registration.
This can be found in the Azure portal under Azure Active Directory -> App
registrations -> [application name] -> Overview -> Application (client) ID.
-|`Client Secret` | A client secret from the Azure app registration. Secrets
can be created in the Azure portal under Azure Active Directory -> App
registrations -> [application name] -> Certificates & secrets -> Client secrets
-> [+] New client secret.
-|`Group Filter Prefix` | Prefix filter for Azure AD groups. Matches against
the group displayName to retrieve only groups with names starting with the
provided prefix.
-|`Group Filter Suffix` | Suffix filter for Azure AD groups. Matches against
the group displayName to retrieve only groups with names ending with the
provided suffix.
-|`Group Filter Substring` | Substring filter for Azure AD groups. Matches
against the group displayName to retrieve only groups with names containing the
provided substring.
-|`Group Filter List Inclusion` | Comma-separated list of Azure AD groups. If
no string-based matching filter (i.e., prefix, suffix, and substring) is
specified, set this property to avoid fetching all groups and users in the
Azure AD tenant.
-|`Page Size` | Page size to use with the Microsoft Graph API. Set to 0 to
disable paging API calls. Default: 50, Max: 999.
-|`Claim for Username` | The property of the user directory object mapped to
the NiFi user name field. Default is 'upn'. 'email' is another option when
`nifi.security.user.oidc.fallback.claims.identifying.user` is set to 'upn'.
-|==================================================================================================================================================
-
-Like LdapUserGroupProvider, the AzureGraphUserGroupProvider configuration is
commented out in the _authorizers.xml_ file. Refer to the comment for a starter
configuration.
-
==== Composite Implementations
Another option for the UserGroupProvider are composite implementations. This
means that multiple sources/implementations can be configured and composed. For
instance, an admin can configure users/groups to be loaded from a file and a
directory server. There are two composite implementations, one that supports
multiple UserGroupProviders and one that supports multiple UserGroupProviders
and a single configurable UserGroupProvider.
diff --git
a/nifi-extension-bundles/nifi-azure-bundle/nifi-azure-graph-authorizer/pom.xml
b/nifi-extension-bundles/nifi-azure-bundle/nifi-azure-graph-authorizer/pom.xml
deleted file mode 100644
index 23dcfac99e..0000000000
---
a/nifi-extension-bundles/nifi-azure-bundle/nifi-azure-graph-authorizer/pom.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- 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.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
- <parent>
- <artifactId>nifi-azure-bundle</artifactId>
- <groupId>org.apache.nifi</groupId>
- <version>2.7.0-SNAPSHOT</version>
- </parent>
- <modelVersion>4.0.0</modelVersion>
- <artifactId>nifi-azure-graph-authorizer</artifactId>
- <packaging>jar</packaging>
- <properties>
- <microsoft-graph.version>2.10.0</microsoft-graph.version>
- </properties>
- <dependencies>
- <dependency>
- <groupId>org.apache.nifi</groupId>
- <artifactId>nifi-framework-api</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.apache.nifi</groupId>
- <artifactId>nifi-utils</artifactId>
- </dependency>
- <dependency>
- <groupId>com.google.code.gson</groupId>
- <artifactId>gson</artifactId>
- </dependency>
- <dependency>
- <groupId>org.jetbrains</groupId>
- <artifactId>annotations</artifactId>
- </dependency>
-
- <dependency>
- <groupId>com.microsoft.graph</groupId>
- <artifactId>microsoft-graph</artifactId>
- <version>${microsoft-graph.version}</version>
- </dependency>
- <dependency>
- <groupId>com.microsoft.azure</groupId>
- <artifactId>msal4j</artifactId>
- </dependency>
- </dependencies>
-</project>
diff --git
a/nifi-extension-bundles/nifi-azure-bundle/nifi-azure-graph-authorizer/src/main/java/org/apache/nifi/authorization/azure/AzureGraphUserGroupProvider.java
b/nifi-extension-bundles/nifi-azure-bundle/nifi-azure-graph-authorizer/src/main/java/org/apache/nifi/authorization/azure/AzureGraphUserGroupProvider.java
deleted file mode 100644
index 54eb113102..0000000000
---
a/nifi-extension-bundles/nifi-azure-bundle/nifi-azure-graph-authorizer/src/main/java/org/apache/nifi/authorization/azure/AzureGraphUserGroupProvider.java
+++ /dev/null
@@ -1,451 +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.authorization.azure;
-
-import com.google.gson.JsonObject;
-import com.microsoft.graph.core.ClientException;
-import com.microsoft.graph.models.extensions.IGraphServiceClient;
-import com.microsoft.graph.options.Option;
-import com.microsoft.graph.options.QueryOption;
-import com.microsoft.graph.requests.extensions.GraphServiceClient;
-import com.microsoft.graph.requests.extensions.IGroupCollectionPage;
-import com.microsoft.graph.requests.extensions.IGroupCollectionRequest;
-import com.microsoft.graph.requests.extensions.IGroupCollectionRequestBuilder;
-import
com.microsoft.graph.requests.extensions.IUserCollectionWithReferencesPage;
-import
com.microsoft.graph.requests.extensions.IUserCollectionWithReferencesRequest;
-import
com.microsoft.graph.requests.extensions.IUserCollectionWithReferencesRequestBuilder;
-import org.apache.nifi.authorization.AuthorizerConfigurationContext;
-import org.apache.nifi.authorization.Group;
-import org.apache.nifi.authorization.User;
-import org.apache.nifi.authorization.UserAndGroups;
-import org.apache.nifi.authorization.UserGroupProvider;
-import org.apache.nifi.authorization.UserGroupProviderInitializationContext;
-import org.apache.nifi.authorization.exception.AuthorizationAccessException;
-import org.apache.nifi.authorization.exception.AuthorizerCreationException;
-import org.apache.nifi.authorization.exception.AuthorizerDestructionException;
-import org.apache.nifi.components.PropertyValue;
-import org.apache.nifi.util.FormatUtils;
-import org.apache.nifi.util.StopWatch;
-import org.apache.nifi.util.StringUtils;
-import org.jetbrains.annotations.NotNull;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicReference;
-
-/**
- * The AzureGraphUserGroupProvider provides support for retrieving users and
- * groups from Azure Active Directory (AAD) using graph rest-api & SDK.
- */
-public class AzureGraphUserGroupProvider implements UserGroupProvider {
- private final static Logger logger =
LoggerFactory.getLogger(AzureGraphUserGroupProvider.class);
-
- private String claimForUserName;
-
- private ScheduledExecutorService scheduler;
-
- public static final String REFRESH_DELAY_PROPERTY = "Refresh Delay";
- private static final long MINIMUM_SYNC_INTERVAL_MILLISECONDS = 10_000;
- public static final String AUTHORITY_ENDPOINT_PROPERTY = "Authority
Endpoint";
- public static final String GRAPH_ENDPOINT_PROPERTY = "Graph Endpoint";
- public static final String GRAPH_SCOPE_PROPERTY = "Graph Scope";
- public static final String TENANT_ID_PROPERTY = "Directory ID";
- public static final String APP_REG_CLIENT_ID_PROPERTY = "Application ID";
- public static final String APP_REG_CLIENT_SECRET_PROPERTY = "Client
Secret";
- // comma separated list of group names to search from AAD
- public static final String GROUP_FILTER_LIST_PROPERTY = "Group Filter List
Inclusion";
- // group filter with startswith
- public static final String GROUP_FILTER_PREFIX_PROPERTY = "Group Filter
Prefix";
- // client side group filter 'endswith' operator, due to support limitation
of azure graph rest-api
- public static final String GROUP_FILTER_SUFFIX_PROPERTY = "Group Filter
Suffix";
- // client side group filter 'contains' operator, due to support limitation
of azure graph rest-api
- public static final String GROUP_FILTER_SUBSTRING_PROPERTY = "Group Filter
Substring";
- public static final String PAGE_SIZE_PROPERTY = "Page Size";
- // default: upn (or userPrincipalName). possible choices ['upn', 'email']
- // this should be matched with oidc configuration in nifi.properties
- public static final String CLAIM_FOR_USERNAME = "Claim for Username";
- public static final String DEFAULT_REFRESH_DELAY = "5 mins";
- public static final String DEFAULT_PAGE_SIZE = "50";
- public static final String DEFAULT_CLAIM_FOR_USERNAME = "upn";
- public static final int MAX_PAGE_SIZE = 999;
- public static final String AZURE_PUBLIC_CLOUD =
"https://login.microsoftonline.com/";
- public static final String AZURE_PUBLIC_GRAPH_DEFAULT_SCOPE =
"https://graph.microsoft.com/.default";
- static final List<String> REST_CALL_KEYWORDS = Arrays.asList("$select",
"$top", "$expand", "$search", "$filter", "$format", "$count", "$skip",
"$orderby");
-
-
- private IGraphServiceClient graphClient;
- private final AtomicReference<ImmutableAzureGraphUserGroup>
azureGraphUserGroupRef = new AtomicReference<>();
-
- @Override
- public Group getGroup(String identifier) throws
AuthorizationAccessException {
- return azureGraphUserGroupRef.get().getGroup(identifier);
- }
-
- @Override
- public Set<Group> getGroups() throws AuthorizationAccessException {
- return azureGraphUserGroupRef.get().getGroups();
- }
-
- @Override
- public User getUser(String identifier) throws AuthorizationAccessException
{
- return azureGraphUserGroupRef.get().getUser(identifier);
- }
-
- @Override
- public UserAndGroups getUserAndGroups(String principalName) throws
AuthorizationAccessException {
- return azureGraphUserGroupRef.get().getUserAndGroups(principalName);
- }
-
- @Override
- public User getUserByIdentity(String principalName) throws
AuthorizationAccessException {
- return
azureGraphUserGroupRef.get().getUserByPrincipalName(principalName);
- }
-
- @Override
- public Set<User> getUsers() throws AuthorizationAccessException {
- return azureGraphUserGroupRef.get().getUsers();
- }
-
- @Override
- public void initialize(UserGroupProviderInitializationContext
initializationContext)
- throws AuthorizerCreationException {
- this.scheduler = Executors.newSingleThreadScheduledExecutor(new
ThreadFactory() {
- @Override
- public Thread newThread(@NotNull Runnable r) {
- final Thread thread =
Executors.defaultThreadFactory().newThread(r);
- thread.setName(String.format("%s (%s) - UserGroup Refresh",
getClass().getSimpleName(), initializationContext.getIdentifier()));
- return thread;
- }
- });
- }
-
- private String getProperty(AuthorizerConfigurationContext authContext,
String propertyName, String defaultValue) {
- final PropertyValue property = authContext.getProperty(propertyName);
-
- if (property != null && property.isSet()) {
- final String value = property.getValue();
- if (StringUtils.isNotBlank(value)) {
- return value;
- }
- }
-
- return defaultValue;
- }
-
- private long getDelayProperty(AuthorizerConfigurationContext authContext,
String propertyName, String defaultValue) {
- final String propertyValue = getProperty(authContext, propertyName,
defaultValue);
- final long syncInterval;
- try {
- syncInterval =
Math.round(FormatUtils.getPreciseTimeDuration(propertyValue,
TimeUnit.MILLISECONDS));
- } catch (final IllegalArgumentException ignored) {
- throw new AuthorizerCreationException(String.format("The %s '%s'
is not a valid time interval.", propertyName, propertyValue));
- }
-
- if (syncInterval < MINIMUM_SYNC_INTERVAL_MILLISECONDS) {
- throw new AuthorizerCreationException(String.format("The %s '%s'
is below the minimum value of '%d ms'", propertyName, propertyValue,
MINIMUM_SYNC_INTERVAL_MILLISECONDS));
- }
- return syncInterval;
- }
-
- private boolean hasReservedKeyword(String prefix) {
- return REST_CALL_KEYWORDS.contains(prefix);
- }
-
- @Override
- public void onConfigured(AuthorizerConfigurationContext
configurationContext) throws AuthorizerCreationException {
- final long fixedDelay = getDelayProperty(configurationContext,
REFRESH_DELAY_PROPERTY, DEFAULT_REFRESH_DELAY);
- final String authorityEndpoint = getProperty(configurationContext,
AUTHORITY_ENDPOINT_PROPERTY, AZURE_PUBLIC_CLOUD);
- final String graphEndpoint = getProperty(configurationContext,
GRAPH_ENDPOINT_PROPERTY, null);
- final String graphScope = getProperty(configurationContext,
GRAPH_SCOPE_PROPERTY, AZURE_PUBLIC_GRAPH_DEFAULT_SCOPE);
- final String tenantId = getProperty(configurationContext,
TENANT_ID_PROPERTY, null);
- final String clientId = getProperty(configurationContext,
APP_REG_CLIENT_ID_PROPERTY, null);
- final String clientSecret = getProperty(configurationContext,
APP_REG_CLIENT_SECRET_PROPERTY, null);
- int pageSize = Integer.parseInt(getProperty(configurationContext,
PAGE_SIZE_PROPERTY, DEFAULT_PAGE_SIZE));
- this.claimForUserName = getProperty(configurationContext,
CLAIM_FOR_USERNAME, DEFAULT_CLAIM_FOR_USERNAME);
- final String providerClassName = getClass().getSimpleName();
- if (StringUtils.isBlank(tenantId)) {
- throw new AuthorizerCreationException(String.format("%s is a
required field for %s", TENANT_ID_PROPERTY, providerClassName));
- }
- if (StringUtils.isBlank(clientId)) {
- throw new AuthorizerCreationException(String.format("%s is a
required field for %s", APP_REG_CLIENT_ID_PROPERTY, providerClassName));
- }
- if (StringUtils.isBlank(clientSecret)) {
- throw new AuthorizerCreationException(String.format("%s is a
required field for %s", APP_REG_CLIENT_SECRET_PROPERTY, providerClassName));
- }
- if (pageSize > MAX_PAGE_SIZE) {
- throw new AuthorizerCreationException(String.format("Max page size
for Microsoft Graph is %d.", MAX_PAGE_SIZE));
- }
-
- try {
- ClientCredentialAuthProvider authProvider = new
ClientCredentialAuthProvider.Builder()
- .authorityEndpoint(authorityEndpoint)
- .tenantId(tenantId)
- .clientId(clientId)
- .clientSecret(clientSecret)
- .graphScope(graphScope)
- .build();
- graphClient =
GraphServiceClient.builder().authenticationProvider(authProvider).buildClient();
- if (!StringUtils.isBlank(graphEndpoint)) {
- graphClient.setServiceRoot(graphEndpoint);
- }
- } catch (final ClientException e) {
- throw new AuthorizerCreationException(String.format("Failed to
create a GraphServiceClient due to %s", e.getMessage()), e);
- }
-
- // first, load list of group name if there is any prefix, suffix,
substring
- // filter defined, paging through groups.
- // then, add additional group list if there is group list inclusion
defined.
- final String prefix = getProperty(configurationContext,
GROUP_FILTER_PREFIX_PROPERTY, null);
- final String suffix = getProperty(configurationContext,
GROUP_FILTER_SUFFIX_PROPERTY, null);
- final String substring = getProperty(configurationContext,
GROUP_FILTER_SUBSTRING_PROPERTY, null);
- final String groupFilterList = getProperty(configurationContext,
GROUP_FILTER_LIST_PROPERTY, null);
-
- // if no group filter is specified, generate exception since we don't
want to
- // load whole groups from AAD.
- if (StringUtils.isBlank(prefix) && StringUtils.isBlank(suffix) &&
StringUtils.isBlank(substring) && StringUtils.isBlank(groupFilterList)) {
- throw new AuthorizerCreationException(String.format("At least one
group filter (%s, %s, %s) should be specified for %s",
- GROUP_FILTER_PREFIX_PROPERTY, GROUP_FILTER_SUFFIX_PROPERTY,
GROUP_FILTER_LIST_PROPERTY, providerClassName));
- }
- // make sure prefix shouldn't have any reserved keywords
- if (hasReservedKeyword(prefix)) {
- throw new AuthorizerCreationException(String.format("Prefix
shouldn't have any reserved keywords ([%s])",
StringUtils.join(REST_CALL_KEYWORDS, ",")));
- }
-
- try {
- refreshUserGroup(groupFilterList, prefix, suffix, substring,
pageSize);
- } catch (final IOException | ClientException e) {
- throw new AuthorizerCreationException(String.format("Failed to
load UserGroup due to %s", e.getMessage()), e);
- }
- scheduler.scheduleWithFixedDelay(() -> {
- try {
- refreshUserGroup(groupFilterList, prefix, suffix, substring,
pageSize);
- } catch (final Throwable t) {
- logger.error("Error refreshing user groups due to {}",
t.getMessage(), t);
- }
- }, fixedDelay, fixedDelay, TimeUnit.MILLISECONDS);
- }
-
- private void refreshUserGroup(String groupFilterList, String prefix,
String suffix, String substring, int pageSize) throws IOException,
ClientException {
- if (logger.isDebugEnabled()) {
- logger.debug("Refreshing user groups");
- }
- final StopWatch stopWatch = new StopWatch(true);
- final Set<String> groupDisplayNames = getGroupsWith(groupFilterList,
prefix, suffix, substring, pageSize);
- refreshUserGroupData(groupDisplayNames, pageSize);
- stopWatch.stop();
- if (logger.isDebugEnabled()) {
- logger.debug("Refreshed {} user groups in {}",
groupDisplayNames.size(), stopWatch.getDuration());
- }
- }
-
- private Set<String> getGroupsWith(String groupFilterList, String prefix,
String suffix, String substring, int pageSize) {
- final Set<String> groupDisplayNames = new HashSet<>();
-
- if (!StringUtils.isBlank(prefix) || !StringUtils.isBlank(suffix) ||
!StringUtils.isBlank(substring)) {
- groupDisplayNames.addAll(queryGroupsWith(prefix, suffix,
substring, pageSize));
- }
-
- if (!StringUtils.isBlank(groupFilterList)) {
- groupDisplayNames.addAll(
- Arrays.stream(groupFilterList.split(","))
- .map(String::trim)
- .filter(s -> !s.isEmpty())
- .toList()
- );
- }
- return Collections.unmodifiableSet(groupDisplayNames);
- }
-
- /**
- * Get a set of group display names after filtering prefix, suffix, and
substring
- * @param prefix prefix filter string matching against displayName of
group directory objects
- * @param suffix suffix filter string matching against displayName of
group directory objects
- * @param substring string matching against displayName of group directory
objects
- * @param pageSize page size to make graph rest calls in pagination
- * @return set of group display names
- */
- private Set<String> queryGroupsWith(String prefix, String suffix, String
substring, int pageSize) {
- final Set<String> groups = new HashSet<>();
- IGroupCollectionRequest gRequest;
- IGroupCollectionPage filterResults;
- if (prefix != null && !prefix.isEmpty()) {
- // build a $filter query option and create a graph request if
prefix is given
- final List<Option> requestOptions = List.of(new
QueryOption("$filter", String.format("startswith(displayName, '%s')", prefix)));
- gRequest =
graphClient.groups().buildRequest(requestOptions).select("displayName");
- } else {
- // default group graph request
- gRequest =
graphClient.groups().buildRequest().select("displayName");
- }
- if (pageSize > 0) {
- gRequest = gRequest.top(pageSize);
- }
- filterResults = gRequest.get();
-
- List<com.microsoft.graph.models.extensions.Group> currentPage =
filterResults.getCurrentPage();
- while (currentPage != null) {
- for (com.microsoft.graph.models.extensions.Group grp :
currentPage) {
- boolean suffixMatches = StringUtils.isEmpty(suffix) ||
grp.displayName.endsWith(suffix);
- boolean substringMatches = StringUtils.isEmpty(substring) ||
grp.displayName.contains(substring);
-
- if (suffixMatches && substringMatches) {
- groups.add(grp.displayName);
- }
- }
- IGroupCollectionRequestBuilder gBuilder =
filterResults.getNextPage();
- if (gBuilder != null) {
- filterResults = gBuilder.buildRequest().get();
- currentPage = filterResults.getCurrentPage();
- } else {
- currentPage = null;
- }
- }
-
- return Collections.unmodifiableSet(groups);
- }
-
- /**
- * Get member users of the given group name
- * @param groupName group name to search for member users
- * @return UserGroupQueryResult
- */
- private UserGroupQueryResult getUsersFrom(String groupName, int pageSize)
throws IOException, ClientException {
- final Set<User> users = new HashSet<>();
-
- final List<Option> requestOptions = List.of(new QueryOption("$filter",
String.format("displayName eq '%s'", groupName)));
- final IGroupCollectionPage results =
graphClient.groups().buildRequest(requestOptions).get();
- final List<com.microsoft.graph.models.extensions.Group> currentPage =
results.getCurrentPage();
-
- if (currentPage != null && !currentPage.isEmpty()) {
- final com.microsoft.graph.models.extensions.Group graphGroup =
results.getCurrentPage().getFirst();
- final Group.Builder groupBuilder =
- new Group.Builder()
- .identifier(graphGroup.id)
- .name(graphGroup.displayName);
-
- IUserCollectionWithReferencesRequest uRequest =
- graphClient.groups(graphGroup.id)
- .transitiveMembersAsUser()
- .buildRequest()
- .select("id, displayName, mail, userPrincipalName");
-
- IUserCollectionWithReferencesPage userpage = uRequest.get();
-
- while (userpage != null && userpage.getCurrentPage() != null) {
- for (com.microsoft.graph.models.extensions.User userDO :
userpage.getCurrentPage()) {
- JsonObject jsonUser = userDO.getRawObject();
- final String idUser;
- if (!jsonUser.get("id").isJsonNull()) {
- idUser = jsonUser.get("id").getAsString();
- } else {
- idUser = "";
- }
- // upn is default fallback claim for userName
- // upn claim maps to 'mail' property in Azure graph
rest-api.
- final String userName;
- if (claimForUserName.equals("email")) {
- // authentication token contains email field, while
graph api returns mail property
- if (!jsonUser.get("mail").isJsonNull()) {
- userName = jsonUser.get("mail").getAsString();
- } else {
- userName =
jsonUser.get("userPrincipalName").getAsString();
- }
- } else {
- userName =
jsonUser.get("userPrincipalName").getAsString();
- }
- final User user = new
User.Builder().identifier(idUser).identity(userName).build();
- users.add(user);
- groupBuilder.addUser(idUser);
- }
- IUserCollectionWithReferencesRequestBuilder nextPageRequest =
userpage.getNextPage();
-
- if (nextPageRequest != null) {
- userpage = nextPageRequest.buildRequest().get();
- } else {
- break;
- }
- }
- final Group group = groupBuilder.build();
- return new UserGroupQueryResult(group, users);
- }
- return null;
- }
-
- /**
- * refresh the user & group data for UserGroupProvider plugin service
- * @param groupDisplayNames a list of group display names
- */
- private void refreshUserGroupData(Set<String> groupDisplayNames, int
pageSize) throws IOException, ClientException {
- Objects.requireNonNull(groupDisplayNames);
-
- final Set<User> users = new HashSet<>();
- final Set<Group> groups = new HashSet<>();
-
- for (String grpFilter : groupDisplayNames) {
- if (logger.isDebugEnabled()) logger.debug("Getting users for group
filter: {}", grpFilter);
- UserGroupQueryResult queryResult = getUsersFrom(grpFilter,
pageSize);
- if (queryResult != null) {
- groups.add(queryResult.getGroup());
- users.addAll(queryResult.getUsers());
- }
- }
- final ImmutableAzureGraphUserGroup azureGraphUserGroup =
ImmutableAzureGraphUserGroup.newInstance(users, groups);
- azureGraphUserGroupRef.set(azureGraphUserGroup);
- }
-
- @Override
- public void preDestruction() throws AuthorizerDestructionException {
- scheduler.shutdown();
- try {
- if (!scheduler.awaitTermination(10000, TimeUnit.MILLISECONDS)) {
- scheduler.shutdownNow();
- }
- } catch (final InterruptedException e) {
- logger.warn("Error shutting down user group refresh scheduler due
to {}", e.getMessage(), e);
- }
- }
-
- private static class UserGroupQueryResult {
- private final Group group;
- private final Set<User> users;
-
- public UserGroupQueryResult(Group group, Set<User> users) {
- this.group = group;
- this.users = users;
- }
-
- public Group getGroup() {
- return this.group;
- }
-
- public Set<User> getUsers() {
- return this.users;
- }
- }
-
-}
-
diff --git
a/nifi-extension-bundles/nifi-azure-bundle/nifi-azure-graph-authorizer/src/main/java/org/apache/nifi/authorization/azure/ClientCredentialAuthProvider.java
b/nifi-extension-bundles/nifi-azure-bundle/nifi-azure-graph-authorizer/src/main/java/org/apache/nifi/authorization/azure/ClientCredentialAuthProvider.java
deleted file mode 100644
index 764e709ba4..0000000000
---
a/nifi-extension-bundles/nifi-azure-bundle/nifi-azure-graph-authorizer/src/main/java/org/apache/nifi/authorization/azure/ClientCredentialAuthProvider.java
+++ /dev/null
@@ -1,191 +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.authorization.azure;
-
-import java.net.MalformedURLException;
-import java.time.Instant;
-import java.time.LocalDateTime;
-import java.time.ZoneId;
-import java.util.Collections;
-import java.util.Date;
-import java.util.Objects;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutionException;
-
-import com.microsoft.aad.msal4j.ClientCredentialFactory;
-import com.microsoft.aad.msal4j.ClientCredentialParameters;
-import com.microsoft.aad.msal4j.ConfidentialClientApplication;
-import com.microsoft.aad.msal4j.IAuthenticationResult;
-import com.microsoft.graph.authentication.IAuthenticationProvider;
-import com.microsoft.graph.http.IHttpRequest;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ClientCredentialAuthProvider implements IAuthenticationProvider {
-
- private final String authorityEndpoint;
- private final String tenantId;
- private final String clientId;
- private final String clientSecret;
- private final String graphScope;
- private LocalDateTime tokenExpiresOnDate;
- private String lastAccessToken;
- private static final Logger logger =
LoggerFactory.getLogger(ClientCredentialAuthProvider.class);
-
- private ClientCredentialAuthProvider(final Builder builder) {
- this.authorityEndpoint = builder.getAuthorityEndpoint();
- this.tenantId = builder.getTenantId();
- this.clientId = builder.getClientId();
- this.clientSecret = builder.getClientSecret();
- this.graphScope = builder.getGraphScope();
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(authorityEndpoint, tenantId, clientId,
clientSecret, graphScope);
- }
-
- @Override
- public String toString() {
- return "{" +
- " authorityDNS='" + authorityEndpoint + "'" +
- ", tenantId='" + tenantId + "'" +
- ", clientId='" + clientId + "'" +
- ", clientSecret='" + clientSecret + "'" +
- ", graphScope='" + graphScope + "'" +
- "}";
- }
-
- private IAuthenticationResult getAccessTokenByClientCredentialGrant()
- throws MalformedURLException, ExecutionException, InterruptedException
{
-
- ConfidentialClientApplication app =
ConfidentialClientApplication.builder(
- this.clientId,
- ClientCredentialFactory.createFromSecret(this.clientSecret))
- .authority(String.format("%s/%s", authorityEndpoint, tenantId))
- .build();
- ClientCredentialParameters clientCredentialParam =
ClientCredentialParameters.builder(
- Collections.singleton(graphScope))
- .build();
-
- CompletableFuture<IAuthenticationResult> future =
app.acquireToken(clientCredentialParam);
- return future.get();
- }
-
- private LocalDateTime convertToLocalDateTime(Date dateToConvert) {
- return Instant.ofEpochMilli(dateToConvert.getTime())
- .atZone(ZoneId.systemDefault())
- .toLocalDateTime();
- }
-
- private String getAccessToken() {
- if ((lastAccessToken == null) || (tokenExpiresOnDate == null) ||
(!tokenExpiresOnDate.isAfter(LocalDateTime.now().plusMinutes(1)))) {
- try {
- IAuthenticationResult result =
getAccessTokenByClientCredentialGrant();
- tokenExpiresOnDate =
convertToLocalDateTime(result.expiresOnDate());
- lastAccessToken = result.accessToken();
- } catch (final Exception e) {
- logger.error("Failed to get access token due to {}",
e.getMessage(), e);
- }
- }
- return lastAccessToken;
- }
-
- @Override
- public void authenticateRequest(IHttpRequest request) {
- String accessToken = getAccessToken();
- if (accessToken != null) {
- request.addHeader("Authorization", "Bearer " + accessToken);
- }
- }
-
- public static class Builder {
-
- private String authorityEndpoint = "";
- private String tenantId = "";
- private String clientId = "";
- private String clientSecret = "";
- private String graphScope = "";
-
- public Builder authorityEndpoint(final String authorityEndpoint) {
- this.authorityEndpoint = authorityEndpoint;
- return this;
- }
-
- public String getAuthorityEndpoint() {
- return this.authorityEndpoint;
- }
-
- public Builder graphScope(final String graphDefaultScope) {
- this.graphScope = graphDefaultScope;
- return this;
- }
-
- public String getGraphScope() {
- return this.graphScope;
- }
-
- public Builder tenantId(final String tenantId) {
- this.tenantId = tenantId;
- return this;
- }
-
- public String getTenantId() {
- return this.tenantId;
- }
-
- public Builder clientId(final String clientId) {
- this.clientId = clientId;
- return this;
- }
-
- public String getClientId() {
- return this.clientId;
- }
-
- public Builder clientSecret(final String clientSecret) {
- this.clientSecret = clientSecret;
- return this;
- }
-
- public String getClientSecret() {
- return this.clientSecret;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(authorityEndpoint, tenantId, clientId,
clientSecret, graphScope);
- }
-
- @Override
- public String toString() {
- return "{" +
- " authorityDNS='" + getAuthorityEndpoint() + "'" +
- ", tenantId='" + getTenantId() + "'" +
- ", clientId='" + getClientId() + "'" +
- ", clientSecret='" + getClientSecret() + "'" +
- ", graphScope='" + getGraphScope() + "'" +
- "}";
- }
- public ClientCredentialAuthProvider build() {
- return new ClientCredentialAuthProvider(this);
- }
- }
-}
-
diff --git
a/nifi-extension-bundles/nifi-azure-bundle/nifi-azure-graph-authorizer/src/main/java/org/apache/nifi/authorization/azure/ImmutableAzureGraphUserGroup.java
b/nifi-extension-bundles/nifi-azure-bundle/nifi-azure-graph-authorizer/src/main/java/org/apache/nifi/authorization/azure/ImmutableAzureGraphUserGroup.java
deleted file mode 100644
index 743623e389..0000000000
---
a/nifi-extension-bundles/nifi-azure-bundle/nifi-azure-graph-authorizer/src/main/java/org/apache/nifi/authorization/azure/ImmutableAzureGraphUserGroup.java
+++ /dev/null
@@ -1,156 +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.authorization.azure;
-
-import org.apache.nifi.authorization.Group;
-import org.apache.nifi.authorization.User;
-import org.apache.nifi.authorization.UserAndGroups;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import static java.util.stream.Collectors.toMap;
-
-public class ImmutableAzureGraphUserGroup {
- private final Set<User> users;
- private final Map<String, User> usersByObjectId;
- private final Map<String, User> usersByPrincipalName;
- private final Map<String, UserAndGroups> usersAndGroupsByUserObjectId;
-
- private final Set<Group> groups;
- private final Map<String, Group> groupsByObjectId;
- private final Map<String, Group> groupsByDisplayName;
-
- private ImmutableAzureGraphUserGroup(
- final Set<User> users,
- final Map<String, User> usersByObjectId,
- final Map<String, User> usersByPrincipalName,
- final Map<String, UserAndGroups> usersAndGroupsByUserObjectId,
- final Set<Group> groups,
- final Map<String, Group> groupsByObjectId,
- final Map<String, Group> groupsByDisplayName) {
-
- this.users = Collections.unmodifiableSet(users);
- this.usersByObjectId = Collections.unmodifiableMap(usersByObjectId);
- this.usersByPrincipalName =
Collections.unmodifiableMap(usersByPrincipalName);
- this.usersAndGroupsByUserObjectId =
Collections.unmodifiableMap(usersAndGroupsByUserObjectId);
-
- this.groups = Collections.unmodifiableSet(groups);
- this.groupsByObjectId = Collections.unmodifiableMap(groupsByObjectId);
- this.groupsByDisplayName =
Collections.unmodifiableMap(groupsByDisplayName);
- }
-
- public Set<User> getUsers() {
- return users;
- }
-
- public User getUser(final String objectId) {
- return usersByObjectId.get(objectId);
- }
-
- public User getUserByPrincipalName(final String principalName) {
- return usersByPrincipalName.get(principalName);
- }
-
- public UserAndGroups getUserAndGroupsByUserObjectId(final String objectId)
{
- return usersAndGroupsByUserObjectId.get(objectId);
- }
-
- public UserAndGroups getUserAndGroups(final String principalName) {
- final User user = getUserByPrincipalName(principalName);
- if (user != null) {
- final String objectId = user.getIdentifier();
- return getUserAndGroupsByUserObjectId(objectId);
- } else {
- // this covers the certificate-based authentication path
- // this path may be called when CompositeUserGroupProvider is used
- return new UserAndGroups() {
- @Override
- public User getUser() {
- return null;
- }
- @Override
- public Set<Group> getGroups() {
- return null;
- }
- };
- }
- }
-
- public Set<Group> getGroups() {
- return groups;
- }
-
- public Group getGroup(final String objectId) {
- return groupsByObjectId.get(objectId);
- }
-
- public Group getGroupByDisplayName(final String displayName) {
- return groupsByDisplayName.get(displayName);
- }
-
- public static ImmutableAzureGraphUserGroup newInstance(final Set<User>
users, final Set<Group> groups) {
- final Map<String, User> usersByObjectId = new HashMap<>();
- final Map<String, User> usersByPrincipalName = new HashMap<>();
-
- users.forEach(user -> {
- usersByObjectId.put(user.getIdentifier(), user);
- usersByPrincipalName.put(user.getIdentity(), user);
- });
-
- final Map<String, Group> groupsByObjectId = new HashMap<>();
- final Map<String, Group> groupsByDisplayName = new HashMap<>();
- final Map<String, Set<Group>> groupsByUserObjectId =
- users.stream().collect(toMap(User::getIdentifier, user -> new
HashSet<>()));
-
- groups.forEach(group -> {
- groupsByObjectId.put(group.getIdentifier(), group);
- groupsByDisplayName.put(group.getName(), group);
- group.getUsers().forEach(user -> {
- groupsByUserObjectId.get(user).add(group);
- });
- });
-
- final Map<String, UserAndGroups> usersAndGroupsByUserObjectId =
- groupsByUserObjectId.entrySet()
- .stream()
- .collect(toMap(Map.Entry::getKey, e -> {
- return new UserAndGroups() {
- @Override public User getUser() {
- return usersByObjectId.get(e.getKey());
- }
- @Override public Set<Group> getGroups() {
- return e.getValue();
- }
- };
- }));
-
- return new ImmutableAzureGraphUserGroup(
- users,
- usersByObjectId,
- usersByPrincipalName,
- usersAndGroupsByUserObjectId,
- groups,
- groupsByObjectId,
- groupsByDisplayName
- );
- }
-}
diff --git
a/nifi-extension-bundles/nifi-azure-bundle/nifi-azure-graph-authorizer/src/main/resources/META-INF/services/org.apache.nifi.authorization.UserGroupProvider
b/nifi-extension-bundles/nifi-azure-bundle/nifi-azure-graph-authorizer/src/main/resources/META-INF/services/org.apache.nifi.authorization.UserGroupProvider
deleted file mode 100755
index d64a7d0173..0000000000
---
a/nifi-extension-bundles/nifi-azure-bundle/nifi-azure-graph-authorizer/src/main/resources/META-INF/services/org.apache.nifi.authorization.UserGroupProvider
+++ /dev/null
@@ -1,15 +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.
-org.apache.nifi.authorization.azure.AzureGraphUserGroupProvider
diff --git a/nifi-extension-bundles/nifi-azure-bundle/nifi-azure-nar/pom.xml
b/nifi-extension-bundles/nifi-azure-bundle/nifi-azure-nar/pom.xml
index 85885fe94e..acec70c0bc 100644
--- a/nifi-extension-bundles/nifi-azure-bundle/nifi-azure-nar/pom.xml
+++ b/nifi-extension-bundles/nifi-azure-bundle/nifi-azure-nar/pom.xml
@@ -36,18 +36,6 @@
<artifactId>nifi-azure-reporting-task</artifactId>
<version>2.7.0-SNAPSHOT</version>
</dependency>
- <dependency>
- <groupId>org.apache.nifi</groupId>
- <artifactId>nifi-azure-graph-authorizer</artifactId>
- <version>2.7.0-SNAPSHOT</version>
- <exclusions>
- <!-- Exclude Guava provided in nifi-azure-services-api-nar -->
- <exclusion>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-azure-services-api-nar</artifactId>
diff --git
a/nifi-extension-bundles/nifi-azure-bundle/nifi-azure-nar/src/main/resources/META-INF/LICENSE
b/nifi-extension-bundles/nifi-azure-bundle/nifi-azure-nar/src/main/resources/META-INF/LICENSE
index 7b49df79ad..98be6d8c90 100644
---
a/nifi-extension-bundles/nifi-azure-bundle/nifi-azure-nar/src/main/resources/META-INF/LICENSE
+++
b/nifi-extension-bundles/nifi-azure-bundle/nifi-azure-nar/src/main/resources/META-INF/LICENSE
@@ -222,30 +222,6 @@
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- The binary distribution of this product bundles 'Bouncy Castle JDK 1.5'
- under an MIT style license.
-
- Copyright (c) 2000 - 2015 The Legion of the Bouncy Castle Inc.
(http://www.bouncycastle.org)
-
- Permission is hereby granted, free of charge, to any person obtaining a
copy
- of this software and associated documentation files (the "Software"), to
deal
- in the Software without restriction, including without limitation the
rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
-
The binary distribution of this product bundles 'Azure SDK for Java' which
is available under an MIT license.
Copyright (c) 2015 Microsoft Azure
@@ -286,28 +262,6 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE
SOFTWARE
- The binary distribution of this product bundles 'Project Lombok 1.18.6'
which is available under an MIT license.
-
- Copyright (C) 2009-2015 The Project Lombok Authors.
-
- Permission is hereby granted, free of charge, to any person obtaining a
copy
- of this software and associated documentation files (the "Software"), to
deal
- in the Software without restriction, including without limitation the
rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
-
This product bundles 'ASM 5.0.4' which is available under a 3-Clause BSD
style license.
For details see https://asm.ow2.io/license.html
@@ -339,55 +293,6 @@
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.
- This product bundles 'NanoHttpd Core 2.3.1' which is available under a
3-Clause BSD license.
- Copyright (c) 2012 - 2016, nanohttpd
-
- Redistribution and use in source and binary forms, with or without
modification,
- are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
this
- list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
notice,
- this list of conditions and the following disclaimer in the
documentation
- and/or other materials provided with the distribution.
-
- 3. Neither the name of the nanohttpd nor the names of its contributors
- may be used to endorse or promote products derived from this software
without
- specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED.
- IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT,
- INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING,
- BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE
- OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED
- OF THE POSSIBILITY OF SUCH DAMAGE.
-
- The binary distribution of this product bundles the 'Stax2 API 4.2' library
which is available under the Simplified BSD License.
-
- Copyright (c) 2008 FasterXML LLC [email protected]
-
- Redistribution and use in source and binary forms, with or without
modification, are permitted
- provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the
- following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED
- WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A
- PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
OR CONTRIBUTORS BE LIABLE FOR ANY
- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
The binary distribution of this product bundles 'Jakarta Activation API
1.2.1' and 'Jakarta XML Binding API 2.3.2' modules under an EDL v1.0 license
Copyright (c) 2007, Eclipse Foundation, Inc. and its licensors.
@@ -407,26 +312,3 @@
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
-
- The binary distribution of this product bundles 'Microsoft Graph SDK for
Java'
- which is available under an MIT license.
-
- Copyright (c) 2018 Microsoft Graph
-
- Permission is hereby granted, free of charge, to any person obtaining a
copy
- of this software and associated documentation files (the "Software"), to
- deal in the Software without restriction, including without limitation the
- rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- sell copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS
- IN THE SOFTWARE.
diff --git
a/nifi-extension-bundles/nifi-azure-bundle/nifi-azure-nar/src/main/resources/META-INF/NOTICE
b/nifi-extension-bundles/nifi-azure-bundle/nifi-azure-nar/src/main/resources/META-INF/NOTICE
index a4fb770588..b4511abc28 100644
---
a/nifi-extension-bundles/nifi-azure-bundle/nifi-azure-nar/src/main/resources/META-INF/NOTICE
+++
b/nifi-extension-bundles/nifi-azure-bundle/nifi-azure-nar/src/main/resources/META-INF/NOTICE
@@ -10,40 +10,10 @@ Apache Software License v2
The following binary components are provided under the Apache Software License
v2
- (ASLv2) Apache Commons Lang
- The following NOTICE information applies:
- Apache Commons Lang
- Copyright 2001-2014 The Apache Software Foundation
-
- This product includes software from the Spring Framework,
- under the Apache License 2.0 (see: StringUtils.containsWhitespace())
-
- (ASLv2) Apache Commons IO
- The following NOTICE information applies:
- Apache Commons IO
- Copyright 2002-2016 The Apache Software Foundation
-
(ASLv2) Google GSON
The following NOTICE information applies:
Copyright 2008 Google Inc.
- (ASLv2) Apache Commons Codec
- The following NOTICE information applies:
- Apache Commons Codec
- Copyright 2002-2014 The Apache Software Foundation
-
- src/test/org/apache/commons/codec/language/DoubleMetaphoneTest.java
- contains test data from http://aspell.net/test/orig/batch0.tab.
- Copyright (C) 2002 Kevin Atkinson ([email protected])
-
-
===============================================================================
-
- The content of package org.apache.commons.codec.language.bm has been
translated
- from the original php source code available at
http://stevemorse.org/phoneticinfo.htm
- with permission from the original authors.
- Original source copyright:
- Copyright (c) 2008 Alexander Beider & Stephen P. Morse.
-
(ASLv2) Jackson JSON processor
The following NOTICE information applies:
# Jackson JSON processor
@@ -67,11 +37,6 @@ The following binary components are provided under the
Apache Software License v
in some artifacts (usually source distributions); but is always available
from the source code management (SCM) system project uses.
- (ASLv2) Guava
- The following NOTICE information applies:
- Guava
- Copyright 2015 The Guava Authors
-
(ASLv2) Apache HttpComponents
The following NOTICE information applies:
Apache HttpClient
@@ -90,11 +55,6 @@ The following binary components are provided under the
Apache Software License v
Java Native Access Platform
Copyright 2013 Timothy Wall, Matthias Bläsing
- (ASLv2) Joda Time
- The following NOTICE information applies:
- This product includes software developed by
- Joda.org (http://www.joda.org/).
-
(ASLv2) Dropwizard Metrics
The following NOTICE information applies:
Dropwizard Metrics
@@ -110,21 +70,11 @@ The following binary components are provided under the
Apache Software License v
Nimbus OAuth 2.0 SDK with OpenID Connect extensions
Copyright 2012-2020, Connect2id Ltd and contributors.
- (ASLv2) Okio
- The following NOTICE information applies:
- Okio
- Copyright 2013 Square, Inc.
-
(ASLv2) Apache Qpid Proton-J
The following NOTICE information applies:
Apache Qpid Proton-J
Copyright 2012-2020 The Apache Software Foundation
- (ASLv2) Retrofit
- The following NOTICE information applies:
- Retrofit
- Copyright 2013 Square, Inc.
-
(ASLv2) RxJava
The following NOTICE information applies:
RxJava
@@ -145,46 +95,11 @@ The following binary components are provided under the
Apache Software License v
Adapter: RxJava 2.6.2
Copyright 2019, Jake Wharton
- (ASLv2) BCrypt Password Hashing Function (at.favre.lib:bcrypt:jar:0.9.0 -
https://github.com/patrickfav/bcrypt)
- The following NOTICE information applies:
- BCrypt Password Hashing Function 0.9.0
- Copyright 2018 Patrick Favre-Bulle
-
- (ASLv2) Bytes Utility Library (at.favre.lib:bytes:jar:1.3.0 -
https://github.com/patrickfav/bytes-java)
- The following NOTICE information applies:
- Bytes Utility Library 1.3.0
- Copyright 2017 Patrick Favre-Bulle
-
- (ASLv2) Converter: Jackson
(com.squareup.retrofit2:converter-jackson:jar:2.5.0)
- The following NOTICE information applies:
- Converter: Jackson 2.5.0
- Copyright 2018, Jake Wharton
-
(ASLv2) Nimbus JOSE+JWT (com.nimbusds:nimbus-jose-jwt:jar:6.0.1 -
https://bitbucket.org/connect2id/nimbus-jose-jwt)
The following NOTICE information applies:
Nimbus JOSE+JWT 6.0.1
Copyright 2018, Connect2id Ltd.
- (ASLv2) OkHttp Logging Interceptor
(com.squareup.okhttp3:logging-interceptor:jar:3.12.2)
- The following NOTICE information applies:
- OkHttp Logging Interceptor 3.12.2
- Copyright 2019 Square, Inc.
-
- (ASLv2) OkHttp (com.squareup.okhttp3:okhttp:jar:3.12.6)
- The following NOTICE information applies:
- OkHttp 3.12.6
- Copyright 2019 Square, Inc.
-
- (ASLv2) OkHttp URLConnection
(com.squareup.okhttp3:okhttp-urlconnection:jar:3.12.2)
- The following NOTICE information applies:
- OkHttp 3.12.2
- Copyright 2019 Square, Inc.
-
- (ASLv2) Woodstox (com.fasterxml.woodstox:woodstox-core:jar:6.1.1 -
https://github.com/FasterXML/woodstox)
- The following NOTICE information applies:
- Woodstox Core 6.1.1
- Copyright 2015, FasterXML, LLC
-
(ASLv2) Non Blocking Reactive Foundation For The JVM
(io.projectreactor:reactor-core:jar:3.3.5.RELEASE -
https://github.com/reactor/reactor-core)
The following NOTICE information applies:
Non Blocking Reactive Foundation For The JVM
@@ -195,19 +110,6 @@ The following binary components are provided under the
Apache Software License v
Reactive Streams Netty Driver
Copyright 2020, Project Reactor
- (ASLv2) Caffeine (com.github.ben-manes.caffeine:caffeine:jar:2.9.2 -
https://github.com/ben-manes/caffeine)
- The following NOTICE information applies:
- Caffeine (caching library)
- Copyright Ben Manes
-
-************************
-Common Development and Distribution License 1.0
-************************
-
-The following binary components are provided under the Common Development and
Distribution License 1.0. See project link for details.
-
- (CDDL 1.0) JavaBeans Activation Framework (JAF)
(javax.activation:activation:jar:1.1 -
http://java.sun.com/products/javabeans/jaf/index.jsp)
-
************************
Common Development and Distribution License 1.1
************************
diff --git a/nifi-extension-bundles/nifi-azure-bundle/pom.xml
b/nifi-extension-bundles/nifi-azure-bundle/pom.xml
index 400965286b..20e2f845ef 100644
--- a/nifi-extension-bundles/nifi-azure-bundle/pom.xml
+++ b/nifi-extension-bundles/nifi-azure-bundle/pom.xml
@@ -36,7 +36,6 @@
<modules>
<module>nifi-azure-processors</module>
<module>nifi-azure-reporting-task</module>
- <module>nifi-azure-graph-authorizer</module>
<module>nifi-azure-nar</module>
<module>nifi-azure-services-api</module>
<module>nifi-azure-services-api-nar</module>
@@ -64,7 +63,7 @@
<artifactId>proton-j</artifactId>
<version>${qpid.proton.version}</version>
</dependency>
- <!-- Set msal4j version for azure-identity and
nifi-azure-graph-authorizer -->
+ <!-- Set msal4j version for azure-identity -->
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>msal4j</artifactId>
diff --git
a/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/conf/authorizers.xml
b/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/conf/authorizers.xml
index 4f2fb936ff..a19ddb31c4 100644
---
a/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/conf/authorizers.xml
+++
b/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/conf/authorizers.xml
@@ -173,50 +173,6 @@
</userGroupProvider>
To enable the ldap-user-group-provider remove 2 lines. This is 2 of 2. -->
- <!--
- The AzureGraphUserGroupProvider fetches users and groups from Azure
Active Directory (AAD) using the Microsoft Graph API.
-
- 'Refresh Delay' - (Optional) Duration of delay between
each user and group refresh. Default is `5 mins`.
- 'Authority Endpoint' - The endpoint of the Azure AD login.
This can be found in the Azure portal under
- Azure Active Directory -> App registrations -> [application name]
-> Endpoints.
- 'Directory ID' - Tenant ID or Directory ID. This can
be found in the Azural portal under
- Azure Active Directory -> App registrations -> [application name]
-> Directory (tenant) ID.
- 'Application ID' - Client ID or Application ID of the
Azure app registration. This can be found in the
- Azure portal under Azure Active Directory -> App registrations ->
[application name] -> Overview -> Application (client) ID.
- 'Client Secret' - A client secret from the Azure app
registration. Secrets can be created in the Azure portal under
- Azure Active Directory -> App registrations -> [application name]
-> Certificates & secrets -> Client secrets -> [+] New client secret.
- 'Group Filter Prefix' - (Optional) Prefix filter for Azure
AD groups. Matches against the group displayName
- to retrieve only groups with names starting with the provided
prefix.
- 'Group Filter Suffix' - (Optional) Suffix filter for Azure
AD groups. Matches against the group displayName
- to retrieve only groups with names ending with the provided suffix.
- 'Group Filter Substring' - (Optional) Substring filter for
Azure AD groups. Matches against the group displayName
- to retrieve only groups with names containing the provided
substring.
- 'Group Filter List Inclusion' - (Optional) Comma-separated list of
Azure AD groups. If no string-based matching filter
- (i.e., prefix, suffix, and substring) is specified, set this
property to avoid fetching all groups and users in the
- Azure AD tenant.
- 'Page Size' - (Optional) Page size to use with the
Microsoft Graph API. Set to 0 to disable paging API
- calls. Default: 50, Max: 999.
- 'Claim for Username' - (Optional) The property of the user
directory object mapped to the NiFi user name field.
- Default is 'upn'. 'email' is another option when
nifi.security.user.oidc.fallback.claims.identifying.user is set to 'upn'.
- -->
- <!-- To enable the azure-graph-user-group-provider remove 2 lines. This is
1 of 2.
- <userGroupProvider>
- <identifier>azure-graph-user-group-provider</identifier>
-
<class>org.apache.nifi.authorization.azure.AzureGraphUserGroupProvider</class>
- <property name="Refresh Delay">5 mins</property>
- <property name="Authority
Endpoint">https://login.microsoftonline.com</property>
- <property name="Directory
ID">XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX</property>
- <property name="Application
ID">XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX</property>
- <property name="Client
Secret">XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</property>
- <property name="Group Filter Prefix"></property>
- <property name="Group Filter Suffix"></property>
- <property name="Group Filter Substring"></property>
- <property name="Group Filter List Inclusion"></property>
- <property name="Page Size"></property>
- <property name="Claim for Username">upn</property>
- </userGroupProvider>
- To enable the azure-graph-user-group-provider remove 2 lines. This is 2 of
2. -->
-
<!--
The CompositeUserGroupProvider will provide support for retrieving
users and groups from multiple sources.