From ab1e0a2ef968190dcf99209249a1877a70c6996d Mon Sep 17 00:00:00 2001 From: Michael Collado Date: Sat, 11 Jan 2025 14:35:20 -0800 Subject: [PATCH] Addresses comments from #623 in ActiveRolesProvider --- .../auth/PolarisPrincipalAuthenticator.java | 4 +-- ...sPrincipalRoleSecurityContextProvider.java | 5 ++++ .../auth/DefaultActiveRolesProvider.java | 27 ++++++++----------- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/dropwizard/service/src/main/java/org/apache/polaris/service/dropwizard/auth/PolarisPrincipalAuthenticator.java b/dropwizard/service/src/main/java/org/apache/polaris/service/dropwizard/auth/PolarisPrincipalAuthenticator.java index b8010cbed..c023738d6 100644 --- a/dropwizard/service/src/main/java/org/apache/polaris/service/dropwizard/auth/PolarisPrincipalAuthenticator.java +++ b/dropwizard/service/src/main/java/org/apache/polaris/service/dropwizard/auth/PolarisPrincipalAuthenticator.java @@ -40,11 +40,11 @@ public class PolarisPrincipalAuthenticator implements ContainerRequestFilter { public void filter(ContainerRequestContext requestContext) throws IOException { String authHeader = requestContext.getHeaderString("Authorization"); if (authHeader == null) { - throw new IOException("Authorization header is missing"); + throw new NotAuthorizedException("Authorization header is missing"); } int spaceIdx = authHeader.indexOf(' '); if (spaceIdx <= 0 || !authHeader.substring(0, spaceIdx).equalsIgnoreCase("Bearer")) { - throw new IOException("Authorization header is not a Bearer token"); + throw new NotAuthorizedException("Authorization header is not a Bearer token"); } String credential = authHeader.substring(spaceIdx + 1); Optional principal = authenticator.authenticate(credential); diff --git a/dropwizard/service/src/main/java/org/apache/polaris/service/dropwizard/auth/PolarisPrincipalRoleSecurityContextProvider.java b/dropwizard/service/src/main/java/org/apache/polaris/service/dropwizard/auth/PolarisPrincipalRoleSecurityContextProvider.java index 619f06fdd..67f41a1d8 100644 --- a/dropwizard/service/src/main/java/org/apache/polaris/service/dropwizard/auth/PolarisPrincipalRoleSecurityContextProvider.java +++ b/dropwizard/service/src/main/java/org/apache/polaris/service/dropwizard/auth/PolarisPrincipalRoleSecurityContextProvider.java @@ -20,6 +20,7 @@ import jakarta.annotation.Priority; import jakarta.inject.Inject; +import jakarta.ws.rs.ForbiddenException; import jakarta.ws.rs.Priorities; import jakarta.ws.rs.container.ContainerRequestContext; import jakarta.ws.rs.container.ContainerRequestFilter; @@ -53,6 +54,10 @@ public void filter(ContainerRequestContext requestContext) throws IOException { public SecurityContext createSecurityContext( SecurityContext ctx, AuthenticatedPolarisPrincipal principal) { Set validRoleNames = activeRolesProvider.getActiveRoles(principal); + if (validRoleNames.isEmpty()) { + LOGGER.warn("Principal {} has no active roles. Request will be denied.", principal.getName()); + throw new ForbiddenException("Principal has no active roles"); + } return new SecurityContext() { @Override public Principal getUserPrincipal() { diff --git a/service/common/src/main/java/org/apache/polaris/service/auth/DefaultActiveRolesProvider.java b/service/common/src/main/java/org/apache/polaris/service/auth/DefaultActiveRolesProvider.java index 186641da5..d2fc798c5 100644 --- a/service/common/src/main/java/org/apache/polaris/service/auth/DefaultActiveRolesProvider.java +++ b/service/common/src/main/java/org/apache/polaris/service/auth/DefaultActiveRolesProvider.java @@ -20,18 +20,16 @@ import jakarta.inject.Inject; import jakarta.inject.Provider; -import java.util.List; import java.util.Set; import java.util.function.Predicate; import java.util.stream.Collectors; -import org.apache.iceberg.exceptions.NotAuthorizedException; import org.apache.polaris.core.PolarisCallContext; import org.apache.polaris.core.auth.AuthenticatedPolarisPrincipal; import org.apache.polaris.core.auth.PolarisGrantManager; import org.apache.polaris.core.context.CallContext; import org.apache.polaris.core.context.RealmContext; +import org.apache.polaris.core.entity.PolarisBaseEntity; import org.apache.polaris.core.entity.PolarisEntity; -import org.apache.polaris.core.entity.PrincipalRoleEntity; import org.apache.polaris.core.persistence.MetaStoreManagerFactory; import org.apache.polaris.core.persistence.PolarisMetaStoreManager; import org.slf4j.Logger; @@ -51,15 +49,13 @@ public class DefaultActiveRolesProvider implements ActiveRolesProvider { @Override public Set getActiveRoles(AuthenticatedPolarisPrincipal principal) { - List activeRoles = - loadActivePrincipalRoles( - principal.getActivatedPrincipalRoleNames(), - principal.getPrincipalEntity(), - metaStoreManagerFactory.getOrCreateMetaStoreManager(realmContextProvider.get())); - return activeRoles.stream().map(PrincipalRoleEntity::getName).collect(Collectors.toSet()); + return loadActivePrincipalRoles( + principal.getActivatedPrincipalRoleNames(), + principal.getPrincipalEntity(), + metaStoreManagerFactory.getOrCreateMetaStoreManager(realmContextProvider.get())); } - protected List loadActivePrincipalRoles( + private Set loadActivePrincipalRoles( Set tokenRoles, PolarisEntity principal, PolarisMetaStoreManager metaStoreManager) { PolarisCallContext polarisContext = CallContext.getCurrentContext().getPolarisCallContext(); PolarisGrantManager.LoadGrantsResult principalGrantResults = @@ -76,12 +72,11 @@ protected List loadActivePrincipalRoles( "Failed to resolve principal roles for principal name={} id={}", principal.getName(), principal.getId()); - throw new NotAuthorizedException("Unable to authenticate"); + return Set.of(); } boolean allRoles = tokenRoles.contains(BasePolarisAuthenticator.PRINCIPAL_ROLE_ALL); - Predicate includeRoleFilter = - allRoles ? r -> true : r -> tokenRoles.contains(r.getName()); - List activeRoles = + Predicate includeRoleFilter = allRoles ? r -> true : r -> tokenRoles.contains(r); + Set activeRoles = principalGrantResults.getGrantRecords().stream() .map( gr -> @@ -89,9 +84,9 @@ protected List loadActivePrincipalRoles( polarisContext, gr.getSecurableCatalogId(), gr.getSecurableId())) .filter(PolarisMetaStoreManager.EntityResult::isSuccess) .map(PolarisMetaStoreManager.EntityResult::getEntity) - .map(PrincipalRoleEntity::of) + .map(PolarisBaseEntity::getName) .filter(includeRoleFilter) - .toList(); + .collect(Collectors.toSet()); if (activeRoles.size() != principalGrantResults.getGrantRecords().size()) { LOGGER .atWarn()