You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by jo...@apache.org on 2019/04/01 20:42:41 UTC
[nifi] 10/18: NIFI-6027
This is an automated email from the ASF dual-hosted git repository.
joewitt pushed a commit to branch NIFI-6169-RC1
in repository https://gitbox.apache.org/repos/asf/nifi.git
commit ac7a56314a5213adf15e4870c97e3a41f59432d1
Author: Matt Gilman <ma...@gmail.com>
AuthorDate: Mon Mar 18 13:01:15 2019 -0400
NIFI-6027
- Allowing user or group existence enforcement to be parameterized.
- Fixing error handling when loading user groups which may have resulted in stack trace leaking.
This closes #3377.
Signed-off-by: Kevin Doran <kd...@apache.org>
---
.../apache/nifi/web/StandardNiFiServiceFacade.java | 70 +++++++++++++---------
.../web/security/NiFiAuthenticationFilter.java | 19 ++++--
2 files changed, 58 insertions(+), 31 deletions(-)
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
index a960dbf..fbce19b 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
@@ -39,8 +39,8 @@ import org.apache.nifi.authorization.User;
import org.apache.nifi.authorization.UserContextKeys;
import org.apache.nifi.authorization.resource.Authorizable;
import org.apache.nifi.authorization.resource.EnforcePolicyPermissionsThroughBaseResource;
-import org.apache.nifi.authorization.resource.ResourceFactory;
import org.apache.nifi.authorization.resource.OperationAuthorizable;
+import org.apache.nifi.authorization.resource.ResourceFactory;
import org.apache.nifi.authorization.user.NiFiUser;
import org.apache.nifi.authorization.user.NiFiUserUtils;
import org.apache.nifi.bundle.BundleCoordinate;
@@ -48,10 +48,10 @@ import org.apache.nifi.cluster.coordination.ClusterCoordinator;
import org.apache.nifi.cluster.coordination.heartbeat.HeartbeatMonitor;
import org.apache.nifi.cluster.coordination.heartbeat.NodeHeartbeat;
import org.apache.nifi.cluster.coordination.node.ClusterRoles;
-import org.apache.nifi.cluster.coordination.node.OffloadCode;
import org.apache.nifi.cluster.coordination.node.DisconnectionCode;
import org.apache.nifi.cluster.coordination.node.NodeConnectionState;
import org.apache.nifi.cluster.coordination.node.NodeConnectionStatus;
+import org.apache.nifi.cluster.coordination.node.OffloadCode;
import org.apache.nifi.cluster.event.NodeEvent;
import org.apache.nifi.cluster.manager.exception.IllegalNodeDeletionException;
import org.apache.nifi.cluster.manager.exception.UnknownNodeException;
@@ -599,8 +599,8 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
authorizable,
() -> accessPolicyDAO.updateAccessPolicy(accessPolicyDTO),
accessPolicy -> {
- final Set<TenantEntity> users = accessPolicy.getUsers().stream().map(mapUserIdToTenantEntity()).collect(Collectors.toSet());
- final Set<TenantEntity> userGroups = accessPolicy.getGroups().stream().map(mapUserGroupIdToTenantEntity()).collect(Collectors.toSet());
+ final Set<TenantEntity> users = accessPolicy.getUsers().stream().map(mapUserIdToTenantEntity(false)).collect(Collectors.toSet());
+ final Set<TenantEntity> userGroups = accessPolicy.getGroups().stream().map(mapUserGroupIdToTenantEntity(false)).collect(Collectors.toSet());
final ComponentReferenceEntity componentReference = createComponentReferenceEntity(accessPolicy.getResource());
return dtoFactory.createAccessPolicyDto(accessPolicy, userGroups, users, componentReference);
});
@@ -618,7 +618,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
usersAuthorizable,
() -> userDAO.updateUser(userDTO),
user -> {
- final Set<TenantEntity> tenantEntities = groups.stream().map(g -> g.getIdentifier()).map(mapUserGroupIdToTenantEntity()).collect(Collectors.toSet());
+ final Set<TenantEntity> tenantEntities = groups.stream().map(g -> g.getIdentifier()).map(mapUserGroupIdToTenantEntity(false)).collect(Collectors.toSet());
final Set<AccessPolicySummaryEntity> policyEntities = policies.stream().map(ap -> createAccessPolicySummaryEntity(ap)).collect(Collectors.toSet());
return dtoFactory.createUserDto(user, tenantEntities, policyEntities);
});
@@ -635,7 +635,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
userGroupsAuthorizable,
() -> userGroupDAO.updateUserGroup(userGroupDTO),
userGroup -> {
- final Set<TenantEntity> tenantEntities = userGroup.getUsers().stream().map(mapUserIdToTenantEntity()).collect(Collectors.toSet());
+ final Set<TenantEntity> tenantEntities = userGroup.getUsers().stream().map(mapUserIdToTenantEntity(false)).collect(Collectors.toSet());
final Set<AccessPolicySummaryEntity> policyEntities = policies.stream().map(ap -> createAccessPolicySummaryEntity(ap)).collect(Collectors.toSet());
return dtoFactory.createUserGroupDto(userGroup, tenantEntities, policyEntities);
}
@@ -1254,7 +1254,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
final User user = userDAO.getUser(userId);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(authorizableLookup.getTenant());
final Set<TenantEntity> userGroups = user != null ? userGroupDAO.getUserGroupsForUser(userId).stream()
- .map(g -> g.getIdentifier()).map(mapUserGroupIdToTenantEntity()).collect(Collectors.toSet()) : null;
+ .map(g -> g.getIdentifier()).map(mapUserGroupIdToTenantEntity(false)).collect(Collectors.toSet()) : null;
final Set<AccessPolicySummaryEntity> policyEntities = user != null ? userGroupDAO.getAccessPoliciesForUser(userId).stream()
.map(ap -> createAccessPolicySummaryEntity(ap)).collect(Collectors.toSet()) : null;
@@ -1289,7 +1289,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
final Group userGroup = userGroupDAO.getUserGroup(userGroupId);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(authorizableLookup.getTenant());
final Set<TenantEntity> users = userGroup != null ? userGroup.getUsers().stream()
- .map(mapUserIdToTenantEntity()).collect(Collectors.toSet()) : null;
+ .map(mapUserIdToTenantEntity(false)).collect(Collectors.toSet()) : null;
final Set<AccessPolicySummaryEntity> policyEntities = userGroupDAO.getAccessPoliciesForUserGroup(userGroup.getIdentifier()).stream()
.map(ap -> createAccessPolicySummaryEntity(ap)).collect(Collectors.toSet());
@@ -1324,8 +1324,8 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
final AccessPolicy accessPolicy = accessPolicyDAO.getAccessPolicy(accessPolicyId);
final ComponentReferenceEntity componentReference = createComponentReferenceEntity(accessPolicy.getResource());
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(authorizableLookup.getAccessPolicyById(accessPolicyId));
- final Set<TenantEntity> userGroups = accessPolicy != null ? accessPolicy.getGroups().stream().map(mapUserGroupIdToTenantEntity()).collect(Collectors.toSet()) : null;
- final Set<TenantEntity> users = accessPolicy != null ? accessPolicy.getUsers().stream().map(mapUserIdToTenantEntity()).collect(Collectors.toSet()) : null;
+ final Set<TenantEntity> userGroups = accessPolicy != null ? accessPolicy.getGroups().stream().map(mapUserGroupIdToTenantEntity(false)).collect(Collectors.toSet()) : null;
+ final Set<TenantEntity> users = accessPolicy != null ? accessPolicy.getUsers().stream().map(mapUserIdToTenantEntity(false)).collect(Collectors.toSet()) : null;
final AccessPolicyDTO snapshot = deleteComponent(
revision,
new Resource() {
@@ -1700,7 +1700,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
final AccessPolicy newAccessPolicy = accessPolicyDAO.createAccessPolicy(accessPolicyDTO);
final ComponentReferenceEntity componentReference = createComponentReferenceEntity(newAccessPolicy.getResource());
final AccessPolicyDTO newAccessPolicyDto = dtoFactory.createAccessPolicyDto(newAccessPolicy,
- newAccessPolicy.getGroups().stream().map(mapUserGroupIdToTenantEntity()).collect(Collectors.toSet()),
+ newAccessPolicy.getGroups().stream().map(mapUserGroupIdToTenantEntity(false)).collect(Collectors.toSet()),
newAccessPolicy.getUsers().stream().map(userId -> {
final RevisionDTO userRevision = dtoFactory.createRevisionDTO(revisionManager.getRevision(userId));
return entityFactory.createTenantEntity(dtoFactory.createTenantDTO(userDAO.getUser(userId)), userRevision,
@@ -1716,7 +1716,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
final String creator = NiFiUserUtils.getNiFiUserIdentity();
final User newUser = userDAO.createUser(userDTO);
final Set<TenantEntity> tenantEntities = userGroupDAO.getUserGroupsForUser(newUser.getIdentifier()).stream()
- .map(g -> g.getIdentifier()).map(mapUserGroupIdToTenantEntity()).collect(Collectors.toSet());
+ .map(g -> g.getIdentifier()).map(mapUserGroupIdToTenantEntity(false)).collect(Collectors.toSet());
final Set<AccessPolicySummaryEntity> policyEntities = userGroupDAO.getAccessPoliciesForUser(newUser.getIdentifier()).stream()
.map(ap -> createAccessPolicySummaryEntity(ap)).collect(Collectors.toSet());
final UserDTO newUserDto = dtoFactory.createUserDto(newUser, tenantEntities, policyEntities);
@@ -1762,7 +1762,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
public UserGroupEntity createUserGroup(final Revision revision, final UserGroupDTO userGroupDTO) {
final String creator = NiFiUserUtils.getNiFiUserIdentity();
final Group newUserGroup = userGroupDAO.createUserGroup(userGroupDTO);
- final Set<TenantEntity> tenantEntities = newUserGroup.getUsers().stream().map(mapUserIdToTenantEntity()).collect(Collectors.toSet());
+ final Set<TenantEntity> tenantEntities = newUserGroup.getUsers().stream().map(mapUserIdToTenantEntity(false)).collect(Collectors.toSet());
final Set<AccessPolicySummaryEntity> policyEntities = userGroupDAO.getAccessPoliciesForUserGroup(newUserGroup.getIdentifier()).stream()
.map(ap -> createAccessPolicySummaryEntity(ap)).collect(Collectors.toSet());
final UserGroupDTO newUserGroupDto = dtoFactory.createUserGroupDto(newUserGroup, tenantEntities, policyEntities);
@@ -3302,39 +3302,39 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
final ComponentReferenceEntity componentReference = createComponentReferenceEntity(accessPolicy.getResource());
return entityFactory.createAccessPolicyEntity(
dtoFactory.createAccessPolicyDto(accessPolicy,
- accessPolicy.getGroups().stream().map(mapUserGroupIdToTenantEntity()).collect(Collectors.toSet()),
- accessPolicy.getUsers().stream().map(mapUserIdToTenantEntity()).collect(Collectors.toSet()), componentReference),
+ accessPolicy.getGroups().stream().map(mapUserGroupIdToTenantEntity(false)).collect(Collectors.toSet()),
+ accessPolicy.getUsers().stream().map(mapUserIdToTenantEntity(false)).collect(Collectors.toSet()), componentReference),
revision, permissions);
}
@Override
public UserEntity getUser(final String userId) {
final User user = userDAO.getUser(userId);
- return createUserEntity(user);
+ return createUserEntity(user, true);
}
@Override
public Set<UserEntity> getUsers() {
final Set<User> users = userDAO.getUsers();
return users.stream()
- .map(user -> createUserEntity(user))
+ .map(user -> createUserEntity(user, false))
.collect(Collectors.toSet());
}
- private UserEntity createUserEntity(final User user) {
+ private UserEntity createUserEntity(final User user, final boolean enforceUserExistence) {
final RevisionDTO userRevision = dtoFactory.createRevisionDTO(revisionManager.getRevision(user.getIdentifier()));
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(authorizableLookup.getTenant());
final Set<TenantEntity> userGroups = userGroupDAO.getUserGroupsForUser(user.getIdentifier()).stream()
- .map(g -> g.getIdentifier()).map(mapUserGroupIdToTenantEntity()).collect(Collectors.toSet());
+ .map(g -> g.getIdentifier()).map(mapUserGroupIdToTenantEntity(enforceUserExistence)).collect(Collectors.toSet());
final Set<AccessPolicySummaryEntity> policyEntities = userGroupDAO.getAccessPoliciesForUser(user.getIdentifier()).stream()
.map(ap -> createAccessPolicySummaryEntity(ap)).collect(Collectors.toSet());
return entityFactory.createUserEntity(dtoFactory.createUserDto(user, userGroups, policyEntities), userRevision, permissions);
}
- private UserGroupEntity createUserGroupEntity(final Group userGroup) {
+ private UserGroupEntity createUserGroupEntity(final Group userGroup, final boolean enforceGroupExistence) {
final RevisionDTO userGroupRevision = dtoFactory.createRevisionDTO(revisionManager.getRevision(userGroup.getIdentifier()));
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(authorizableLookup.getTenant());
- final Set<TenantEntity> users = userGroup.getUsers().stream().map(mapUserIdToTenantEntity()).collect(Collectors.toSet());
+ final Set<TenantEntity> users = userGroup.getUsers().stream().map(mapUserIdToTenantEntity(enforceGroupExistence)).collect(Collectors.toSet());
final Set<AccessPolicySummaryEntity> policyEntities = userGroupDAO.getAccessPoliciesForUserGroup(userGroup.getIdentifier()).stream()
.map(ap -> createAccessPolicySummaryEntity(ap)).collect(Collectors.toSet());
return entityFactory.createUserGroupEntity(dtoFactory.createUserGroupDto(userGroup, users, policyEntities), userGroupRevision, permissions);
@@ -3343,14 +3343,14 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
@Override
public UserGroupEntity getUserGroup(final String userGroupId) {
final Group userGroup = userGroupDAO.getUserGroup(userGroupId);
- return createUserGroupEntity(userGroup);
+ return createUserGroupEntity(userGroup, true);
}
@Override
public Set<UserGroupEntity> getUserGroups() {
final Set<Group> userGroups = userGroupDAO.getUserGroups();
return userGroups.stream()
- .map(userGroup -> createUserGroupEntity(userGroup))
+ .map(userGroup -> createUserGroupEntity(userGroup, false))
.collect(Collectors.toSet());
}
@@ -4740,18 +4740,34 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
}
/* reusable function declarations for converting ids to tenant entities */
- private Function<String, TenantEntity> mapUserGroupIdToTenantEntity() {
+ private Function<String, TenantEntity> mapUserGroupIdToTenantEntity(final boolean enforceGroupExistence) {
return userGroupId -> {
final RevisionDTO userGroupRevision = dtoFactory.createRevisionDTO(revisionManager.getRevision(userGroupId));
- return entityFactory.createTenantEntity(dtoFactory.createTenantDTO(userGroupDAO.getUserGroup(userGroupId)), userGroupRevision,
+
+ final Group group;
+ if (enforceGroupExistence || userGroupDAO.hasUserGroup(userGroupId)) {
+ group = userGroupDAO.getUserGroup(userGroupId);
+ } else {
+ group = new Group.Builder().identifier(userGroupId).name("Group ID - " + userGroupId + " (removed externally)").build();
+ }
+
+ return entityFactory.createTenantEntity(dtoFactory.createTenantDTO(group), userGroupRevision,
dtoFactory.createPermissionsDto(authorizableLookup.getTenant()));
};
}
- private Function<String, TenantEntity> mapUserIdToTenantEntity() {
+ private Function<String, TenantEntity> mapUserIdToTenantEntity(final boolean enforceUserExistence) {
return userId -> {
final RevisionDTO userRevision = dtoFactory.createRevisionDTO(revisionManager.getRevision(userId));
- return entityFactory.createTenantEntity(dtoFactory.createTenantDTO(userDAO.getUser(userId)), userRevision,
+
+ final User user;
+ if (enforceUserExistence || userDAO.hasUser(userId)) {
+ user = userDAO.getUser(userId);
+ } else {
+ user = new User.Builder().identifier(userId).identity("User ID - " + userId + " (removed externally)").build();
+ }
+
+ return entityFactory.createTenantEntity(dtoFactory.createTenantDTO(user), userRevision,
dtoFactory.createPermissionsDto(authorizableLookup.getTenant()));
};
}
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/NiFiAuthenticationFilter.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/NiFiAuthenticationFilter.java
index 75f1c56..030b19e 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/NiFiAuthenticationFilter.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/NiFiAuthenticationFilter.java
@@ -67,7 +67,6 @@ public abstract class NiFiAuthenticationFilter extends GenericFilterBean {
}
private void authenticate(final HttpServletRequest request, final HttpServletResponse response, final FilterChain chain) throws IOException, ServletException {
- String dnChain = null;
try {
final Authentication authenticationRequest = attemptAuthentication(request);
if (authenticationRequest != null) {
@@ -79,13 +78,25 @@ public abstract class NiFiAuthenticationFilter extends GenericFilterBean {
final Authentication authenticated = authenticationManager.authenticate(authenticationRequest);
successfulAuthorization(request, response, authenticated);
}
-
- // continue
- chain.doFilter(request, response);
} catch (final AuthenticationException ae) {
// invalid authentication - always error out
unsuccessfulAuthorization(request, response, ae);
+ return;
+ } catch (final Exception e) {
+ log.error(String.format("Unable to authorize: %s", e.getMessage()), e);
+
+ // set the response status
+ response.setContentType("text/plain");
+ response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+
+ // other exception - always error out
+ PrintWriter out = response.getWriter();
+ out.println(String.format("Failed to authorize request. Please contact the system administrator."));
+ return;
}
+
+ // continue
+ chain.doFilter(request, response);
}
/**