HBASE-14122 Client API for determining if server side supports cell level security
This commit is contained in:
parent
beb1f1d358
commit
5e5bcceb53
|
@ -18,7 +18,6 @@
|
|||
*/
|
||||
package org.apache.hadoop.hbase.client;
|
||||
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
@ -39,6 +38,7 @@ import org.apache.hadoop.hbase.TableName;
|
|||
import org.apache.hadoop.hbase.TableNotFoundException;
|
||||
import org.apache.hadoop.hbase.classification.InterfaceAudience;
|
||||
import org.apache.hadoop.hbase.classification.InterfaceStability;
|
||||
import org.apache.hadoop.hbase.client.security.SecurityCapability;
|
||||
import org.apache.hadoop.hbase.ipc.CoprocessorRpcChannel;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.AdminProtos;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos;
|
||||
|
@ -1546,4 +1546,11 @@ public interface Admin extends Abortable, Closeable {
|
|||
*/
|
||||
AdminProtos.GetRegionInfoResponse.CompactionState getMobCompactionState(final TableName tableName)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* Return the set of supported security capabilities.
|
||||
* @throws IOException
|
||||
* @throws UnsupportedOperationException
|
||||
*/
|
||||
List<SecurityCapability> getSecurityCapabilities() throws IOException;
|
||||
}
|
||||
|
|
|
@ -296,4 +296,5 @@ public interface ClusterConnection extends HConnection {
|
|||
* @return the configured client backoff policy
|
||||
*/
|
||||
ClientBackoffPolicy getBackoffPolicy();
|
||||
|
||||
}
|
||||
|
|
|
@ -56,6 +56,8 @@ import org.apache.hadoop.hbase.protobuf.generated.ClientProtos;
|
|||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsBalancerEnabledRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsBalancerEnabledResponse;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SecurityCapabilitiesRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SecurityCapabilitiesResponse;
|
||||
import org.apache.hadoop.hbase.quotas.ThrottlingException;
|
||||
import org.apache.hadoop.hbase.regionserver.RegionServerStoppedException;
|
||||
import org.apache.hadoop.hbase.security.User;
|
||||
|
@ -71,6 +73,7 @@ import org.apache.hadoop.ipc.RemoteException;
|
|||
import org.apache.zookeeper.KeeperException;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.io.InterruptedIOException;
|
||||
|
@ -1728,6 +1731,12 @@ class ConnectionImplementation implements ClusterConnection, Closeable {
|
|||
IsBalancerEnabledRequest request) throws ServiceException {
|
||||
return stub.isBalancerEnabled(controller, request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecurityCapabilitiesResponse getSecurityCapabilities(RpcController controller,
|
||||
SecurityCapabilitiesRequest request) throws ServiceException {
|
||||
return stub.getSecurityCapabilities(controller, request);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -62,6 +62,7 @@ import org.apache.hadoop.hbase.UnknownRegionException;
|
|||
import org.apache.hadoop.hbase.ZooKeeperConnectionException;
|
||||
import org.apache.hadoop.hbase.classification.InterfaceAudience;
|
||||
import org.apache.hadoop.hbase.classification.InterfaceStability;
|
||||
import org.apache.hadoop.hbase.client.security.SecurityCapability;
|
||||
import org.apache.hadoop.hbase.exceptions.DeserializationException;
|
||||
import org.apache.hadoop.hbase.exceptions.TimeoutIOException;
|
||||
import org.apache.hadoop.hbase.ipc.CoprocessorRpcChannel;
|
||||
|
@ -132,6 +133,7 @@ import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.ModifyTableRespon
|
|||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.MoveRegionRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.RestoreSnapshotRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.RestoreSnapshotResponse;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SecurityCapabilitiesRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SetBalancerRunningRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.ShutdownRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SnapshotRequest;
|
||||
|
@ -4623,4 +4625,23 @@ public class HBaseAdmin implements Admin {
|
|||
+ " regions are online; retries exhausted.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SecurityCapability> getSecurityCapabilities() throws IOException {
|
||||
try {
|
||||
return executeCallable(new MasterCallable<List<SecurityCapability>>(getConnection()) {
|
||||
@Override
|
||||
public List<SecurityCapability> call(int callTimeout) throws ServiceException {
|
||||
SecurityCapabilitiesRequest req = SecurityCapabilitiesRequest.newBuilder().build();
|
||||
return ProtobufUtil.toSecurityCapabilityList(
|
||||
master.getSecurityCapabilities(null, req).getCapabilitiesList());
|
||||
}
|
||||
});
|
||||
} catch (IOException e) {
|
||||
if (e instanceof RemoteException) {
|
||||
e = ((RemoteException)e).unwrapRemoteException();
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
/**
|
||||
*
|
||||
* 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.hadoop.hbase.client.security;
|
||||
|
||||
import org.apache.hadoop.hbase.classification.InterfaceAudience;
|
||||
import org.apache.hadoop.hbase.classification.InterfaceStability;
|
||||
|
||||
/**
|
||||
* Available security capabilities
|
||||
*/
|
||||
@InterfaceAudience.Public
|
||||
@InterfaceStability.Evolving
|
||||
public enum SecurityCapability {
|
||||
// Note to implementors: These must match the numbering of Capability values in MasterProtos
|
||||
SIMPLE_AUTHENTICATION(0),
|
||||
SECURE_AUTHENTICATION(1),
|
||||
AUTHORIZATION(2),
|
||||
CELL_AUTHORIZATION(3),
|
||||
CELL_VISIBILITY(4);
|
||||
|
||||
private int value;
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return toString();
|
||||
}
|
||||
|
||||
private SecurityCapability(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public static SecurityCapability valueOf(int value) {
|
||||
switch (value) {
|
||||
case 0: return SIMPLE_AUTHENTICATION;
|
||||
case 1: return SECURE_AUTHENTICATION;
|
||||
case 2: return AUTHORIZATION;
|
||||
case 3: return CELL_AUTHORIZATION;
|
||||
case 4: return CELL_VISIBILITY;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown SecurityCapability value " + value);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -65,6 +65,7 @@ import org.apache.hadoop.hbase.client.Put;
|
|||
import org.apache.hadoop.hbase.client.Result;
|
||||
import org.apache.hadoop.hbase.client.Scan;
|
||||
import org.apache.hadoop.hbase.client.metrics.ScanMetrics;
|
||||
import org.apache.hadoop.hbase.client.security.SecurityCapability;
|
||||
import org.apache.hadoop.hbase.exceptions.DeserializationException;
|
||||
import org.apache.hadoop.hbase.filter.ByteArrayComparable;
|
||||
import org.apache.hadoop.hbase.filter.Filter;
|
||||
|
@ -115,6 +116,7 @@ import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.RegionInfo;
|
|||
import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.RegionSpecifier;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.RegionSpecifier.RegionSpecifierType;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MapReduceProtos;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.CreateTableRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetTableDescriptorsResponse;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.MasterService;
|
||||
|
@ -3136,4 +3138,23 @@ public final class ProtobufUtil {
|
|||
builder.setSrcChecksum(VersionInfo.getSrcChecksum());
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert SecurityCapabilitiesResponse.Capability to SecurityCapability
|
||||
* @param caps capabilities returned in the SecurityCapabilitiesResponse message
|
||||
* @return the converted list of SecurityCapability elements
|
||||
*/
|
||||
public static List<SecurityCapability> toSecurityCapabilityList(
|
||||
List<MasterProtos.SecurityCapabilitiesResponse.Capability> capabilities) {
|
||||
List<SecurityCapability> scList = new ArrayList<>(capabilities.size());
|
||||
for (MasterProtos.SecurityCapabilitiesResponse.Capability c: capabilities) {
|
||||
try {
|
||||
scList.add(SecurityCapability.valueOf(c.getNumber()));
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Unknown capability, just ignore it. We don't understand the new capability
|
||||
// but don't care since by definition we cannot take advantage of it.
|
||||
}
|
||||
}
|
||||
return scList;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ import org.apache.hadoop.hbase.classification.InterfaceStability;
|
|||
import org.apache.hadoop.hbase.client.Admin;
|
||||
import org.apache.hadoop.hbase.client.Connection;
|
||||
import org.apache.hadoop.hbase.client.Table;
|
||||
import org.apache.hadoop.hbase.client.security.SecurityCapability;
|
||||
import org.apache.hadoop.hbase.ipc.CoprocessorRpcChannel;
|
||||
import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos;
|
||||
|
@ -48,6 +49,28 @@ public class AccessControlClient {
|
|||
public static final TableName ACL_TABLE_NAME =
|
||||
TableName.valueOf(NamespaceDescriptor.SYSTEM_NAMESPACE_NAME_STR, "acl");
|
||||
|
||||
/**
|
||||
* Return true if authorization is supported and enabled
|
||||
* @param connection The connection to use
|
||||
* @return true if authorization is supported and enabled, false otherwise
|
||||
* @throws IOException
|
||||
*/
|
||||
public static boolean isAuthorizationEnabled(Connection connection) throws IOException {
|
||||
return connection.getAdmin().getSecurityCapabilities()
|
||||
.contains(SecurityCapability.AUTHORIZATION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if cell authorization is supported and enabled
|
||||
* @param connection The connection to use
|
||||
* @return true if cell authorization is supported and enabled, false otherwise
|
||||
* @throws IOException
|
||||
*/
|
||||
public static boolean isCellAuthorizationEnabled(Connection connection) throws IOException {
|
||||
return connection.getAdmin().getSecurityCapabilities()
|
||||
.contains(SecurityCapability.CELL_AUTHORIZATION);
|
||||
}
|
||||
|
||||
private static BlockingInterface getAccessControlServiceStub(Table ht)
|
||||
throws IOException {
|
||||
CoprocessorRpcChannel service = ht.coprocessorService(HConstants.EMPTY_START_ROW);
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.apache.hadoop.hbase.client.Connection;
|
|||
import org.apache.hadoop.hbase.client.ConnectionFactory;
|
||||
import org.apache.hadoop.hbase.client.Table;
|
||||
import org.apache.hadoop.hbase.client.coprocessor.Batch;
|
||||
import org.apache.hadoop.hbase.client.security.SecurityCapability;
|
||||
import org.apache.hadoop.hbase.ipc.BlockingRpcCallback;
|
||||
import org.apache.hadoop.hbase.ipc.ServerRpcController;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.VisibilityLabelsProtos.GetAuthsRequest;
|
||||
|
@ -54,6 +55,17 @@ import com.google.protobuf.ServiceException;
|
|||
@InterfaceStability.Evolving
|
||||
public class VisibilityClient {
|
||||
|
||||
/**
|
||||
* Return true if cell visibility features are supported and enabled
|
||||
* @param connection The connection to use
|
||||
* @return true if cell visibility features are supported and enabled, false otherwise
|
||||
* @throws IOException
|
||||
*/
|
||||
public static boolean isCellVisibilityEnabled(Connection connection) throws IOException {
|
||||
return connection.getAdmin().getSecurityCapabilities()
|
||||
.contains(SecurityCapability.CELL_VISIBILITY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method for adding label to the system.
|
||||
*
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -450,6 +450,21 @@ message MajorCompactionTimestampResponse {
|
|||
required int64 compaction_timestamp = 1;
|
||||
}
|
||||
|
||||
message SecurityCapabilitiesRequest {
|
||||
}
|
||||
|
||||
message SecurityCapabilitiesResponse {
|
||||
enum Capability {
|
||||
SIMPLE_AUTHENTICATION = 0;
|
||||
SECURE_AUTHENTICATION = 1;
|
||||
AUTHORIZATION = 2;
|
||||
CELL_AUTHORIZATION = 3;
|
||||
CELL_VISIBILITY = 4;
|
||||
}
|
||||
|
||||
repeated Capability capabilities = 1;
|
||||
}
|
||||
|
||||
service MasterService {
|
||||
/** Used by the client to get the number of regions that have received the updated schema */
|
||||
rpc GetSchemaAlterStatus(GetSchemaAlterStatusRequest)
|
||||
|
@ -681,4 +696,8 @@ service MasterService {
|
|||
|
||||
rpc getProcedureResult(GetProcedureResultRequest)
|
||||
returns(GetProcedureResultResponse);
|
||||
|
||||
/** Returns the security capabilities in effect on the cluster */
|
||||
rpc getSecurityCapabilities(SecurityCapabilitiesRequest)
|
||||
returns(SecurityCapabilitiesResponse);
|
||||
}
|
||||
|
|
|
@ -21,7 +21,9 @@ package org.apache.hadoop.hbase.master;
|
|||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
@ -140,6 +142,9 @@ import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.RestoreSnapshotRe
|
|||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.RestoreSnapshotResponse;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.RunCatalogScanRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.RunCatalogScanResponse;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SecurityCapabilitiesRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SecurityCapabilitiesResponse;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SecurityCapabilitiesResponse.Capability;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SetBalancerRunningRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SetBalancerRunningResponse;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SetQuotaRequest;
|
||||
|
@ -167,6 +172,9 @@ import org.apache.hadoop.hbase.protobuf.generated.RegionServerStatusProtos.Repor
|
|||
import org.apache.hadoop.hbase.protobuf.generated.RegionServerStatusProtos.ReportRegionStateTransitionRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.RegionServerStatusProtos.ReportRegionStateTransitionResponse;
|
||||
import org.apache.hadoop.hbase.regionserver.RSRpcServices;
|
||||
import org.apache.hadoop.hbase.security.User;
|
||||
import org.apache.hadoop.hbase.security.access.AccessController;
|
||||
import org.apache.hadoop.hbase.security.visibility.VisibilityController;
|
||||
import org.apache.hadoop.hbase.snapshot.ClientSnapshotDescriptionUtils;
|
||||
import org.apache.hadoop.hbase.snapshot.SnapshotDescriptionUtils;
|
||||
import org.apache.hadoop.hbase.util.Bytes;
|
||||
|
@ -1506,4 +1514,44 @@ public class MasterRpcServices extends RSRpcServices
|
|||
response.setEnabled(master.isBalancerOn());
|
||||
return response.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the security capabilities in effect on the cluster
|
||||
*/
|
||||
@Override
|
||||
public SecurityCapabilitiesResponse getSecurityCapabilities(RpcController controller,
|
||||
SecurityCapabilitiesRequest request) throws ServiceException {
|
||||
SecurityCapabilitiesResponse.Builder response = SecurityCapabilitiesResponse.newBuilder();
|
||||
try {
|
||||
master.checkInitialized();
|
||||
Set<Capability> capabilities = new HashSet<>();
|
||||
// Authentication
|
||||
if (User.isHBaseSecurityEnabled(master.getConfiguration())) {
|
||||
capabilities.add(Capability.SECURE_AUTHENTICATION);
|
||||
} else {
|
||||
capabilities.add(Capability.SIMPLE_AUTHENTICATION);
|
||||
}
|
||||
// The AccessController can provide AUTHORIZATION and CELL_AUTHORIZATION
|
||||
if (master.cpHost != null &&
|
||||
master.cpHost.findCoprocessor(AccessController.class.getName()) != null) {
|
||||
if (AccessController.isAuthorizationSupported(master.getConfiguration())) {
|
||||
capabilities.add(Capability.AUTHORIZATION);
|
||||
}
|
||||
if (AccessController.isCellAuthorizationSupported(master.getConfiguration())) {
|
||||
capabilities.add(Capability.CELL_AUTHORIZATION);
|
||||
}
|
||||
}
|
||||
// The VisibilityController can provide CELL_VISIBILITY
|
||||
if (master.cpHost != null &&
|
||||
master.cpHost.findCoprocessor(VisibilityController.class.getName()) != null) {
|
||||
if (VisibilityController.isCellAuthorizationSupported(master.getConfiguration())) {
|
||||
capabilities.add(Capability.CELL_VISIBILITY);
|
||||
}
|
||||
}
|
||||
response.addAllCapabilities(capabilities);
|
||||
} catch (IOException e) {
|
||||
throw new ServiceException(e);
|
||||
}
|
||||
return response.build();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -208,6 +208,15 @@ public class AccessController extends BaseMasterAndRegionObserver
|
|||
/** if the ACL table is available, only relevant in the master */
|
||||
private volatile boolean aclTabAvailable = false;
|
||||
|
||||
public static boolean isAuthorizationSupported(Configuration conf) {
|
||||
return conf.getBoolean(User.HBASE_SECURITY_AUTHORIZATION_CONF_KEY, true);
|
||||
}
|
||||
|
||||
public static boolean isCellAuthorizationSupported(Configuration conf) {
|
||||
return isAuthorizationSupported(conf) &&
|
||||
(HFile.getFormatVersion(conf) >= HFile.MIN_FORMAT_VERSION_WITH_TAGS);
|
||||
}
|
||||
|
||||
public Region getRegion() {
|
||||
return regionEnv != null ? regionEnv.getRegion() : null;
|
||||
}
|
||||
|
@ -923,7 +932,7 @@ public class AccessController extends BaseMasterAndRegionObserver
|
|||
CompoundConfiguration conf = new CompoundConfiguration();
|
||||
conf.add(env.getConfiguration());
|
||||
|
||||
authorizationEnabled = conf.getBoolean(User.HBASE_SECURITY_AUTHORIZATION_CONF_KEY, true);
|
||||
authorizationEnabled = isAuthorizationSupported(conf);
|
||||
if (!authorizationEnabled) {
|
||||
LOG.warn("The AccessController has been loaded with authorization checks disabled.");
|
||||
}
|
||||
|
@ -931,7 +940,7 @@ public class AccessController extends BaseMasterAndRegionObserver
|
|||
shouldCheckExecPermission = conf.getBoolean(AccessControlConstants.EXEC_PERMISSION_CHECKS_KEY,
|
||||
AccessControlConstants.DEFAULT_EXEC_PERMISSION_CHECKS);
|
||||
|
||||
cellFeaturesEnabled = HFile.getFormatVersion(conf) >= HFile.MIN_FORMAT_VERSION_WITH_TAGS;
|
||||
cellFeaturesEnabled = (HFile.getFormatVersion(conf) >= HFile.MIN_FORMAT_VERSION_WITH_TAGS);
|
||||
if (!cellFeaturesEnabled) {
|
||||
LOG.info("A minimum HFile version of " + HFile.MIN_FORMAT_VERSION_WITH_TAGS
|
||||
+ " is required to persist cell ACLs. Consider setting " + HFile.FORMAT_VERSION_KEY
|
||||
|
|
|
@ -148,11 +148,19 @@ public class VisibilityController extends BaseMasterAndRegionObserver implements
|
|||
RESERVED_VIS_TAG_TYPES.add(TagType.STRING_VIS_TAG_TYPE);
|
||||
}
|
||||
|
||||
public static boolean isAuthorizationSupported(Configuration conf) {
|
||||
return conf.getBoolean(User.HBASE_SECURITY_AUTHORIZATION_CONF_KEY, true);
|
||||
}
|
||||
|
||||
public static boolean isCellAuthorizationSupported(Configuration conf) {
|
||||
return isAuthorizationSupported(conf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(CoprocessorEnvironment env) throws IOException {
|
||||
this.conf = env.getConfiguration();
|
||||
|
||||
authorizationEnabled = conf.getBoolean(User.HBASE_SECURITY_AUTHORIZATION_CONF_KEY, true);
|
||||
authorizationEnabled = isAuthorizationSupported(conf);
|
||||
if (!authorizationEnabled) {
|
||||
LOG.warn("The VisibilityController has been loaded with authorization checks disabled.");
|
||||
}
|
||||
|
|
|
@ -67,6 +67,7 @@ import org.apache.hadoop.hbase.client.Result;
|
|||
import org.apache.hadoop.hbase.client.ResultScanner;
|
||||
import org.apache.hadoop.hbase.client.Scan;
|
||||
import org.apache.hadoop.hbase.client.Table;
|
||||
import org.apache.hadoop.hbase.client.security.SecurityCapability;
|
||||
import org.apache.hadoop.hbase.coprocessor.CoprocessorHost;
|
||||
import org.apache.hadoop.hbase.coprocessor.CoprocessorService;
|
||||
import org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment;
|
||||
|
@ -317,6 +318,16 @@ public class TestAccessController extends SecureTestUtil {
|
|||
TEST_TABLE.getNamespaceAsString()).size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSecurityCapabilities() throws Exception {
|
||||
List<SecurityCapability> capabilities = TEST_UTIL.getConnection().getAdmin()
|
||||
.getSecurityCapabilities();
|
||||
assertTrue("AUTHORIZATION capability is missing",
|
||||
capabilities.contains(SecurityCapability.AUTHORIZATION));
|
||||
assertTrue("CELL_AUTHORIZATION capability is missing",
|
||||
capabilities.contains(SecurityCapability.CELL_AUTHORIZATION));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTableCreate() throws Exception {
|
||||
AccessTestAction createTable = new AccessTestAction() {
|
||||
|
|
|
@ -55,6 +55,7 @@ import org.apache.hadoop.hbase.client.ResultScanner;
|
|||
import org.apache.hadoop.hbase.client.RowMutations;
|
||||
import org.apache.hadoop.hbase.client.Scan;
|
||||
import org.apache.hadoop.hbase.client.Table;
|
||||
import org.apache.hadoop.hbase.client.security.SecurityCapability;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.RegionActionResult;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.VisibilityLabelsProtos.GetAuthsResponse;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.VisibilityLabelsProtos.VisibilityLabelsResponse;
|
||||
|
@ -116,6 +117,14 @@ public abstract class TestVisibilityLabels {
|
|||
killedRS = false;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSecurityCapabilities() throws Exception {
|
||||
List<SecurityCapability> capabilities = TEST_UTIL.getConnection().getAdmin()
|
||||
.getSecurityCapabilities();
|
||||
assertTrue("CELL_VISIBILITY capability is missing",
|
||||
capabilities.contains(SecurityCapability.CELL_VISIBILITY));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleVisibilityLabels() throws Exception {
|
||||
TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
|
||||
|
|
|
@ -1031,5 +1031,10 @@ module Hbase
|
|||
end
|
||||
end
|
||||
|
||||
#----------------------------------------------------------------------------------------------
|
||||
# Get security capabilities
|
||||
def get_security_capabilities
|
||||
@admin.getSecurityCapabilities
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -182,10 +182,23 @@ module Hbase
|
|||
end
|
||||
end
|
||||
|
||||
# Make sure that security tables are available
|
||||
# Make sure that security features are available
|
||||
def security_available?()
|
||||
raise(ArgumentError, "DISABLED: Security features are not available") \
|
||||
unless exists?(org.apache.hadoop.hbase.security.access.AccessControlLists::ACL_TABLE_NAME)
|
||||
caps = []
|
||||
begin
|
||||
# Try the getSecurityCapabilities API where supported.
|
||||
# We only need to look at AUTHORIZATION, the AccessController doesn't support
|
||||
# CELL_AUTHORIZATION without AUTHORIZATION also available.
|
||||
caps = @admin.getSecurityCapabilities
|
||||
rescue
|
||||
# If we are unable to use getSecurityCapabilities, fall back with a check for
|
||||
# deployment of the ACL table
|
||||
raise(ArgumentError, "DISABLED: Security features are not available") unless \
|
||||
exists?(org.apache.hadoop.hbase.security.access.AccessControlLists::ACL_TABLE_NAME)
|
||||
return
|
||||
end
|
||||
raise(ArgumentError, "DISABLED: Security features are not available") unless \
|
||||
caps.include? org.apache.hadoop.hbase.client.security.SecurityCapability::AUTHORIZATION
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -35,7 +35,7 @@ module Hbase
|
|||
end
|
||||
|
||||
def add_labels(*args)
|
||||
lables_table_available?
|
||||
visibility_feature_available?
|
||||
# Normalize args
|
||||
if args.kind_of?(Array)
|
||||
labels = [ args ].flatten.compact
|
||||
|
@ -63,7 +63,7 @@ module Hbase
|
|||
end
|
||||
|
||||
def set_auths(user, *args)
|
||||
lables_table_available?
|
||||
visibility_feature_available?
|
||||
# Normalize args
|
||||
if args.kind_of?(Array)
|
||||
auths = [ args ].flatten.compact
|
||||
|
@ -88,7 +88,7 @@ module Hbase
|
|||
end
|
||||
|
||||
def get_auths(user)
|
||||
lables_table_available?
|
||||
visibility_feature_available?
|
||||
begin
|
||||
response = VisibilityClient.getAuths(@connection, user)
|
||||
if response.nil?
|
||||
|
@ -102,7 +102,7 @@ module Hbase
|
|||
end
|
||||
|
||||
def list_labels(regex = ".*")
|
||||
lables_table_available?
|
||||
visibility_feature_available?
|
||||
begin
|
||||
response = VisibilityClient.listLabels(@connection, regex)
|
||||
if response.nil?
|
||||
|
@ -116,7 +116,7 @@ module Hbase
|
|||
end
|
||||
|
||||
def clear_auths(user, *args)
|
||||
lables_table_available?
|
||||
visibility_feature_available?
|
||||
# Normalize args
|
||||
if args.kind_of?(Array)
|
||||
auths = [ args ].flatten.compact
|
||||
|
@ -141,9 +141,20 @@ module Hbase
|
|||
end
|
||||
|
||||
# Make sure that lables table is available
|
||||
def lables_table_available?()
|
||||
raise(ArgumentError, "DISABLED: Visibility labels feature is not available") \
|
||||
unless exists?(VisibilityConstants::LABELS_TABLE_NAME)
|
||||
def visibility_feature_available?()
|
||||
caps = []
|
||||
begin
|
||||
# Try the getSecurityCapabilities API where supported.
|
||||
caps = @admin.getSecurityCapabilities
|
||||
rescue
|
||||
# If we are unable to use getSecurityCapabilities, fall back with a check for
|
||||
# deployment of the labels table
|
||||
raise(ArgumentError, "DISABLED: Visibility labels feature is not available") unless \
|
||||
exists?(VisibilityConstants::LABELS_TABLE_NAME)
|
||||
return
|
||||
end
|
||||
raise(ArgumentError, "DISABLED: Visibility labels feature is not available") unless \
|
||||
caps.include? org.apache.hadoop.hbase.client.security.SecurityCapability::CELL_VISIBILITY
|
||||
end
|
||||
|
||||
# Does table exist?
|
||||
|
|
|
@ -396,6 +396,7 @@ Shell.load_command_group(
|
|||
:full_name => 'SECURITY TOOLS',
|
||||
:comment => "NOTE: Above commands are only applicable if running with the AccessController coprocessor",
|
||||
:commands => %w[
|
||||
list_security_capabilities
|
||||
grant
|
||||
revoke
|
||||
user_permission
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
# 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.
|
||||
#
|
||||
|
||||
module Shell
|
||||
module Commands
|
||||
class ListSecurityCapabilities < Command
|
||||
def help
|
||||
return <<-EOF
|
||||
List supported security capabilities
|
||||
|
||||
Example:
|
||||
hbase> list_security_capabilities
|
||||
EOF
|
||||
end
|
||||
|
||||
def command()
|
||||
begin
|
||||
list = admin.get_security_capabilities
|
||||
list.each do |s|
|
||||
puts s.getName
|
||||
end
|
||||
return list.map { |s| s.getName() }
|
||||
rescue Exception => e
|
||||
if e.to_s.include? "UnsupportedOperationException"
|
||||
puts "ERROR: Master does not support getSecurityCapabilities"
|
||||
return []
|
||||
end
|
||||
raise e
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue