use of io.cdap.cdap.security.spi.authorization.AccessController in project cdap by caskdata.
the class AccessControllerInstantiator method get.
/**
* Returns an instance of the configured {@link AccessController} extension, or of {@link NoOpAccessController}, if
* authorization is disabled.
*/
@Override
public AccessController get() {
if (!cConf.getBoolean(Constants.Security.Authorization.ENABLED)) {
LOG.debug("Authorization is disabled. Authorization can be enabled by setting " + Constants.Security.Authorization.ENABLED + " to true.");
return NOOP_ACCESS_CONTROLLER;
}
if (!cConf.getBoolean(Constants.Security.ENABLED)) {
LOG.warn("Authorization is enabled. However, authentication is disabled. Authorization policies will not be " + "enforced. To enforce authorization policies please enable both authorization, by setting " + Constants.Security.Authorization.ENABLED + " to true and authentication, by setting " + Constants.Security.ENABLED + "to true.");
return NOOP_ACCESS_CONTROLLER;
}
// Authorization is enabled
AccessController accessController = this.accessController;
if (accessController != null) {
return accessController;
}
synchronized (this) {
accessController = this.accessController;
if (accessController != null) {
return accessController;
}
if (closed) {
throw new RuntimeException("Cannot create AccessController due to resources were closed");
}
String accessControllerExtensionJarPath = cConf.get(Constants.Security.Authorization.EXTENSION_JAR_PATH);
String accessControllerExtraClasspath = cConf.get(Constants.Security.Authorization.EXTENSION_EXTRA_CLASSPATH);
if (Strings.isNullOrEmpty(accessControllerExtensionJarPath)) {
throw new IllegalArgumentException(String.format("Access control extension jar path not found in configuration. Please set %s in " + "cdap-site.xml to the fully qualified path of the jar file to use as the authorization " + "backend.", Constants.Security.Authorization.EXTENSION_JAR_PATH));
}
try {
File accessControllerExtensionJar = new File(accessControllerExtensionJarPath);
ensureValidAuthExtensionJar(accessControllerExtensionJar);
accessControllerClassLoader = createAccessControllerClassLoader(accessControllerExtensionJar, accessControllerExtraClasspath);
this.accessController = accessController = createAccessController(accessControllerClassLoader);
return accessController;
} catch (Exception e) {
throw Throwables.propagate(e);
}
}
}
use of io.cdap.cdap.security.spi.authorization.AccessController in project cdap by caskdata.
the class DefaultAccessEnforcerTest method testIsVisible.
@Test
public void testIsVisible() throws IOException, AccessException {
ControllerWrapper controllerWrapper = createControllerWrapper(CCONF, SCONF, null);
AccessController accessController = controllerWrapper.accessController;
DefaultAccessEnforcer authEnforcementService = controllerWrapper.defaultAccessEnforcer;
NamespaceId ns1 = new NamespaceId("ns1");
NamespaceId ns2 = new NamespaceId("ns2");
DatasetId ds11 = ns1.dataset("ds11");
DatasetId ds12 = ns1.dataset("ds12");
DatasetId ds21 = ns2.dataset("ds21");
DatasetId ds22 = ns2.dataset("ds22");
DatasetId ds23 = ns2.dataset("ds33");
Set<NamespaceId> namespaces = ImmutableSet.of(ns1, ns2);
// Alice has access on ns1, ns2, ds11, ds21, ds23, Bob has access on ds11, ds12, ds22
accessController.grant(Authorizable.fromEntityId(ns1), ALICE, Collections.singleton(StandardPermission.UPDATE));
accessController.grant(Authorizable.fromEntityId(ns2), ALICE, Collections.singleton(StandardPermission.UPDATE));
accessController.grant(Authorizable.fromEntityId(ds11), ALICE, Collections.singleton(StandardPermission.GET));
accessController.grant(Authorizable.fromEntityId(ds11), BOB, Collections.singleton(StandardPermission.UPDATE));
accessController.grant(Authorizable.fromEntityId(ds21), ALICE, Collections.singleton(StandardPermission.UPDATE));
accessController.grant(Authorizable.fromEntityId(ds12), BOB, Collections.singleton(StandardPermission.UPDATE));
accessController.grant(Authorizable.fromEntityId(ds12), BOB, EnumSet.allOf(StandardPermission.class));
accessController.grant(Authorizable.fromEntityId(ds21), ALICE, Collections.singleton(StandardPermission.UPDATE));
accessController.grant(Authorizable.fromEntityId(ds23), ALICE, Collections.singleton(StandardPermission.UPDATE));
accessController.grant(Authorizable.fromEntityId(ds22), BOB, Collections.singleton(StandardPermission.UPDATE));
Assert.assertEquals(namespaces.size(), authEnforcementService.isVisible(namespaces, ALICE).size());
// bob should also be able to list two namespaces since he has privileges on the dataset in both namespaces
Assert.assertEquals(namespaces.size(), authEnforcementService.isVisible(namespaces, BOB).size());
Set<DatasetId> expectedDatasetIds = ImmutableSet.of(ds11, ds21, ds23);
Assert.assertEquals(expectedDatasetIds.size(), authEnforcementService.isVisible(expectedDatasetIds, ALICE).size());
expectedDatasetIds = ImmutableSet.of(ds12, ds22);
// this will be empty since now isVisible will not check the hierarchy privilege for the parent of the entity
Assert.assertEquals(Collections.EMPTY_SET, authEnforcementService.isVisible(expectedDatasetIds, ALICE));
expectedDatasetIds = ImmutableSet.of(ds11, ds12, ds22);
Assert.assertEquals(expectedDatasetIds.size(), authEnforcementService.isVisible(expectedDatasetIds, BOB).size());
expectedDatasetIds = ImmutableSet.of(ds21, ds23);
Assert.assertTrue(authEnforcementService.isVisible(expectedDatasetIds, BOB).isEmpty());
// Verify the metrics context was called with correct metrics
verify(controllerWrapper.mockMetricsContext, times(6)).increment(Constants.Metrics.Authorization.NON_INTERNAL_VISIBILITY_CHECK_COUNT, 1);
verify(controllerWrapper.mockMetricsContext, times(6)).gauge(eq(Constants.Metrics.Authorization.EXTENSION_VISIBILITY_MILLIS), any(Long.class));
}
use of io.cdap.cdap.security.spi.authorization.AccessController in project cdap by caskdata.
the class DefaultAccessEnforcerTest method verifyDisabled.
private void verifyDisabled(CConfiguration cConf) throws IOException, AccessException {
ControllerWrapper controllerWrapper = createControllerWrapper(cConf, SCONF, null);
AccessController accessController = controllerWrapper.accessController;
DefaultAccessEnforcer authEnforcementService = controllerWrapper.defaultAccessEnforcer;
DatasetId ds = NS.dataset("ds");
// All enforcement operations should succeed, since authorization is disabled
accessController.grant(Authorizable.fromEntityId(ds), BOB, ImmutableSet.of(StandardPermission.UPDATE));
authEnforcementService.enforce(NS, ALICE, StandardPermission.UPDATE);
authEnforcementService.enforce(ds, BOB, StandardPermission.UPDATE);
authEnforcementService.enforce(NS, BOB, StandardPermission.GET);
authEnforcementService.enforce(ds, BOB, StandardPermission.GET);
Assert.assertEquals(2, authEnforcementService.isVisible(ImmutableSet.<EntityId>of(NS, ds), BOB).size());
// Verify the metrics context was not called
verify(controllerWrapper.mockMetricsContext, times(0)).increment(any(String.class), any(Long.class));
verify(controllerWrapper.mockMetricsContext, times(0)).gauge(any(String.class), any(Long.class));
}
use of io.cdap.cdap.security.spi.authorization.AccessController in project cdap by caskdata.
the class DefaultAccessEnforcerTest method testIsVisibleWithEncryptedCredential.
@Test
public void testIsVisibleWithEncryptedCredential() throws IOException, AccessException, CipherException, GeneralSecurityException {
SConfiguration sConfCopy = enableCredentialEncryption();
TinkCipher cipher = new TinkCipher(sConfCopy);
String cred = cipher.encryptToBase64("credential".getBytes(StandardCharsets.UTF_8), null);
Principal userWithCredEncrypted = new Principal("userFoo", Principal.PrincipalType.USER, null, new Credential(cred, Credential.CredentialType.EXTERNAL_ENCRYPTED));
ControllerWrapper controllerWrapper = createControllerWrapper(CCONF, sConfCopy, null);
AccessController accessController = controllerWrapper.accessController;
DefaultAccessEnforcer accessEnforcer = controllerWrapper.defaultAccessEnforcer;
Set<NamespaceId> namespaces = ImmutableSet.of(NS);
Assert.assertEquals(0, accessEnforcer.isVisible(namespaces, userWithCredEncrypted).size());
accessController.grant(Authorizable.fromEntityId(NS), userWithCredEncrypted, ImmutableSet.of(StandardPermission.GET, StandardPermission.UPDATE));
Assert.assertEquals(1, accessEnforcer.isVisible(namespaces, userWithCredEncrypted).size());
// Verify the metrics context was called with correct metrics
verify(controllerWrapper.mockMetricsContext, times(2)).increment(Constants.Metrics.Authorization.NON_INTERNAL_VISIBILITY_CHECK_COUNT, 1);
verify(controllerWrapper.mockMetricsContext, times(2)).gauge(eq(Constants.Metrics.Authorization.EXTENSION_VISIBILITY_MILLIS), any(Long.class));
}
use of io.cdap.cdap.security.spi.authorization.AccessController in project cdap by caskdata.
the class DefaultAccessEnforcerTest method testAuthEnforceWithBadEncryptedCredential.
@Test
public void testAuthEnforceWithBadEncryptedCredential() throws IOException, AccessException, CipherException, GeneralSecurityException {
thrown.expect(Exception.class);
thrown.expectMessage("Failed to decrypt credential in principle:");
SConfiguration sConfCopy = enableCredentialEncryption();
TinkCipher cipher = new TinkCipher(sConfCopy);
String badCipherCred = Base64.getEncoder().encodeToString("invalid encrypted credential".getBytes());
Principal userWithCredEncrypted = new Principal("userFoo", Principal.PrincipalType.USER, null, new Credential(badCipherCred, Credential.CredentialType.EXTERNAL_ENCRYPTED));
ControllerWrapper controllerWrapper = createControllerWrapper(CCONF, sConfCopy, null);
AccessController accessController = controllerWrapper.accessController;
DefaultAccessEnforcer accessEnforcer = controllerWrapper.defaultAccessEnforcer;
accessController.grant(Authorizable.fromEntityId(NS), userWithCredEncrypted, ImmutableSet.of(StandardPermission.GET, StandardPermission.GET));
accessEnforcer.enforce(NS, userWithCredEncrypted, StandardPermission.GET);
// Verify the metrics context was not called
verify(controllerWrapper.mockMetricsContext, times(0)).increment(any(String.class), any(Long.class));
verify(controllerWrapper.mockMetricsContext, times(0)).gauge(any(String.class), any(Long.class));
}
Aggregations