NIFI-11492 Allow authorization to proceed based on request groups even if user does not exist

This closes #7425

Signed-off-by: David Handermann <exceptionfactory@apache.org>
This commit is contained in:
Bryan Bende 2023-06-22 12:08:00 -04:00 committed by exceptionfactory
parent bd33f2c911
commit 40014486a4
No known key found for this signature in database
GPG Key ID: 29B6A52D2AAE8DBA
2 changed files with 69 additions and 13 deletions

View File

@ -87,11 +87,6 @@ public class StandardManagedAuthorizer implements ManagedAuthorizer {
final UserAndGroups userAndGroups = userGroupProvider.getUserAndGroups(request.getIdentity());
final User user = userAndGroups.getUser();
if (user == null) {
return AuthorizationResult.denied(String.format("Unknown user with identity '%s'.", request.getIdentity()));
}
// combine groups from incoming request with groups from UserAndGroups because the request may contain groups from
// an external identity provider and the membership may not be maintained with in any of the UserGroupProviders
@ -100,9 +95,9 @@ public class StandardManagedAuthorizer implements ManagedAuthorizer {
final Set<Group> allGroups = new HashSet<>();
allGroups.addAll(userGroups == null ? Collections.emptySet() : userGroups);
allGroups.addAll(requestGroups == null ? Collections.emptySet() : requestGroups);
allGroups.addAll(requestGroups);
if (policy.getUsers().contains(user.getIdentifier()) || containsGroup(allGroups, policy)) {
if (containsUser(userAndGroups.getUser(), policy) || containsGroup(allGroups, policy)) {
return AuthorizationResult.approved();
}
@ -147,6 +142,20 @@ public class StandardManagedAuthorizer implements ManagedAuthorizer {
return false;
}
/**
* Determines if the policy contains the user's identifier.
*
* @param user the user
* @param policy the policy
* @return true if the user is non-null and the user's identifies is contained in the policy's users
*/
private boolean containsUser(final User user, final AccessPolicy policy) {
if (user == null || policy.getUsers().isEmpty()) {
return false;
}
return policy.getUsers().contains(user.getIdentifier());
}
@Override
public String getFingerprint() throws AuthorizationAccessException {
XMLStreamWriter writer = null;

View File

@ -366,6 +366,59 @@ public class StandardManagedAuthorizerTest {
assertEquals(AuthorizationResult.approved(), managedAuthorizer.authorize(request));
}
@Test
public void testAuthorizationByRequestGroupsAndUserNotInUserGroupProvider() {
final String userIdentity = "userIdentity1";
final String groupIdentifier = "groupIdentifier1";
// group membership will come from the groups on the request
final Group group = new Group.Builder()
.identifier(groupIdentifier)
.name(groupIdentifier)
.build();
final AccessPolicy policy = new AccessPolicy.Builder()
.identifier("1")
.resource(TEST_RESOURCE.getIdentifier())
.addGroup(groupIdentifier)
.action(RequestAction.READ)
.build();
final ConfigurableUserGroupProvider userGroupProvider = mock(ConfigurableUserGroupProvider.class);
when(userGroupProvider.getUserAndGroups(userIdentity)).thenReturn(new UserAndGroups() {
// user does not exist in UGP
@Override
public User getUser() {
return null;
}
// no groups for the user in the UGP, groups come from request
@Override
public Set<Group> getGroups() {
return Collections.emptySet();
}
});
final ConfigurableAccessPolicyProvider accessPolicyProvider = mock(ConfigurableAccessPolicyProvider.class);
when(accessPolicyProvider.getAccessPolicy(TEST_RESOURCE.getIdentifier(), RequestAction.READ)).thenReturn(policy);
when(accessPolicyProvider.getUserGroupProvider()).thenReturn(userGroupProvider);
when(userGroupProvider.getGroupByName(group.getName())).thenReturn(group);
// simulate groups being passed in on request from NiFiUser getAllGroups()
final AuthorizationRequest request = new AuthorizationRequest.Builder()
.identity(userIdentity)
.groups(Collections.singleton(group.getName()))
.resource(TEST_RESOURCE)
.action(RequestAction.READ)
.accessAttempt(true)
.anonymous(false)
.build();
final StandardManagedAuthorizer managedAuthorizer = getStandardManagedAuthorizer(accessPolicyProvider);
assertEquals(AuthorizationResult.approved(), managedAuthorizer.authorize(request));
}
@Test
public void testResourceNotFound() {
final String userIdentity = "userIdentity1";
@ -391,14 +444,8 @@ public class StandardManagedAuthorizerTest {
@Test
public void testUnauthorizedDueToUnknownUser() {
final String userIdentifier = "userIdentifier1";
final String userIdentity = "userIdentity1";
final String notUser1Identity = "not userIdentity1";
final User user = new User.Builder()
.identity(userIdentity)
.identifier(userIdentifier)
.build();
final AccessPolicy policy = new AccessPolicy.Builder()
.identifier("1")
.resource(TEST_RESOURCE.getIdentifier())