Skip to content

Commit 268bcce

Browse files
meiyiinfraio
authored andcommitted
HBASE-22208 Create access checker and expose it in RS
Signed-off-by: Guanghao Zhang <zghao@apache.org>
1 parent 9e2181c commit 268bcce

File tree

18 files changed

+252
-193
lines changed

18 files changed

+252
-193
lines changed

hbase-rsgroup/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupAdminEndpoint.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@
8282
import org.apache.hadoop.hbase.security.UserProvider;
8383
import org.apache.hadoop.hbase.security.access.AccessChecker;
8484
import org.apache.hadoop.hbase.security.access.Permission.Action;
85-
import org.apache.hadoop.hbase.zookeeper.ZKWatcher;
8685
import org.apache.yetus.audience.InterfaceAudience;
8786
import org.slf4j.Logger;
8887
import org.slf4j.LoggerFactory;
@@ -120,16 +119,14 @@ public void start(CoprocessorEnvironment env) throws IOException {
120119
if (!RSGroupableBalancer.class.isAssignableFrom(clazz)) {
121120
throw new IOException("Configured balancer does not support RegionServer groups.");
122121
}
123-
ZKWatcher zk = ((HasMasterServices)env).getMasterServices().getZooKeeper();
124-
accessChecker = new AccessChecker(env.getConfiguration(), zk);
122+
accessChecker = ((HasMasterServices) env).getMasterServices().getAccessChecker();
125123

126124
// set the user-provider.
127125
this.userProvider = UserProvider.instantiate(env.getConfiguration());
128126
}
129127

130128
@Override
131129
public void stop(CoprocessorEnvironment env) {
132-
accessChecker.stop();
133130
}
134131

135132
@Override

hbase-rsgroup/src/test/java/org/apache/hadoop/hbase/rsgroup/TestRSGroupsWithACL.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919

2020
import static org.apache.hadoop.hbase.AuthUtil.toGroupEntry;
2121
import static org.junit.Assert.assertEquals;
22-
import static org.junit.Assert.assertTrue;
2322
import static org.junit.Assert.fail;
2423

2524
import org.apache.hadoop.conf.Configuration;
@@ -34,7 +33,6 @@
3433
import org.apache.hadoop.hbase.coprocessor.CoprocessorHost;
3534
import org.apache.hadoop.hbase.security.User;
3635
import org.apache.hadoop.hbase.security.access.AccessControlClient;
37-
import org.apache.hadoop.hbase.security.access.AuthManager;
3836
import org.apache.hadoop.hbase.security.access.Permission;
3937
import org.apache.hadoop.hbase.security.access.PermissionStorage;
4038
import org.apache.hadoop.hbase.security.access.SecureTestUtil;
@@ -203,8 +201,6 @@ private static void cleanUp() throws Exception {
203201
public static void tearDownAfterClass() throws Exception {
204202
cleanUp();
205203
TEST_UTIL.shutdownMiniCluster();
206-
int total = AuthManager.getTotalRefCount();
207-
assertTrue("Unexpected reference count: " + total, total == 0);
208204
}
209205

210206
private static void configureRSGroupAdminEndpoint(Configuration conf) {

hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -916,7 +916,7 @@ public ExecProcedureResponse execProcedure(RpcController controller,
916916
+ desc.getSignature()));
917917
}
918918
LOG.info(master.getClientIdAuditPrefix() + " procedure request for: " + desc.getSignature());
919-
mpm.checkPermissions(desc, accessChecker, RpcServer.getRequestUser().orElse(null));
919+
mpm.checkPermissions(desc, getAccessChecker(), RpcServer.getRequestUser().orElse(null));
920920
mpm.execProcedure(desc);
921921
// send back the max amount of time the client should wait for the procedure
922922
// to complete
@@ -2816,10 +2816,10 @@ public HasUserPermissionsResponse hasUserPermissions(RpcController controller,
28162816
caller = new InputUser(userName, groups.toArray(new String[groups.size()]));
28172817
}
28182818
List<Boolean> hasUserPermissions = new ArrayList<>();
2819-
if (accessChecker != null) {
2819+
if (getAccessChecker() != null) {
28202820
for (Permission permission : permissions) {
28212821
boolean hasUserPermission =
2822-
accessChecker.hasUserPermission(caller, "hasUserPermissions", permission);
2822+
getAccessChecker().hasUserPermission(caller, "hasUserPermissions", permission);
28232823
hasUserPermissions.add(hasUserPermission);
28242824
}
28252825
} else {

hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterServices.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@
5151
import org.apache.hadoop.hbase.replication.ReplicationPeerConfig;
5252
import org.apache.hadoop.hbase.replication.ReplicationPeerDescription;
5353
import org.apache.hadoop.hbase.replication.SyncReplicationState;
54+
import org.apache.hadoop.hbase.security.access.AccessChecker;
55+
import org.apache.hadoop.hbase.security.access.ZKPermissionWatcher;
5456
import org.apache.yetus.audience.InterfaceAudience;
5557

5658
import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;
@@ -517,4 +519,14 @@ long transitReplicationPeerSyncReplicationState(String peerId, SyncReplicationSt
517519
default SplitWALManager getSplitWALManager(){
518520
return null;
519521
}
522+
523+
/**
524+
* @return the {@link AccessChecker}
525+
*/
526+
AccessChecker getAccessChecker();
527+
528+
/**
529+
* @return the {@link ZKPermissionWatcher}
530+
*/
531+
ZKPermissionWatcher getZKPermissionWatcher();
520532
}

hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,8 @@
145145
import org.apache.hadoop.hbase.security.Superusers;
146146
import org.apache.hadoop.hbase.security.User;
147147
import org.apache.hadoop.hbase.security.UserProvider;
148+
import org.apache.hadoop.hbase.security.access.AccessChecker;
149+
import org.apache.hadoop.hbase.security.access.ZKPermissionWatcher;
148150
import org.apache.hadoop.hbase.trace.SpanReceiverHost;
149151
import org.apache.hadoop.hbase.trace.TraceUtil;
150152
import org.apache.hadoop.hbase.util.Addressing;
@@ -3660,6 +3662,16 @@ public Optional<MobFileCache> getMobFileCache() {
36603662
return Optional.ofNullable(this.mobFileCache);
36613663
}
36623664

3665+
@Override
3666+
public AccessChecker getAccessChecker() {
3667+
return rpcServices.getAccessChecker();
3668+
}
3669+
3670+
@Override
3671+
public ZKPermissionWatcher getZKPermissionWatcher() {
3672+
return rpcServices.getZkPermissionWatcher();
3673+
}
3674+
36633675
/**
36643676
* @return : Returns the ConfigurationManager object for testing purposes.
36653677
*/

hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RSRpcServices.java

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,9 @@
131131
import org.apache.hadoop.hbase.security.Superusers;
132132
import org.apache.hadoop.hbase.security.User;
133133
import org.apache.hadoop.hbase.security.access.AccessChecker;
134+
import org.apache.hadoop.hbase.security.access.NoopAccessChecker;
134135
import org.apache.hadoop.hbase.security.access.Permission;
136+
import org.apache.hadoop.hbase.security.access.ZKPermissionWatcher;
135137
import org.apache.hadoop.hbase.util.Bytes;
136138
import org.apache.hadoop.hbase.util.DNS;
137139
import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
@@ -144,6 +146,7 @@
144146
import org.apache.hadoop.hbase.wal.WALSplitter;
145147
import org.apache.hadoop.hbase.zookeeper.ZKWatcher;
146148
import org.apache.yetus.audience.InterfaceAudience;
149+
import org.apache.zookeeper.KeeperException;
147150
import org.slf4j.Logger;
148151
import org.slf4j.LoggerFactory;
149152

@@ -344,12 +347,8 @@ public class RSRpcServices implements HBaseRPCErrorHandler,
344347

345348
final AtomicBoolean clearCompactionQueues = new AtomicBoolean(false);
346349

347-
// We want to vet all accesses at the point of entry itself; limiting scope of access checker
348-
// instance to only this class to prevent its use from spreading deeper into implementation.
349-
// Initialized in start() since AccessChecker needs ZKWatcher which is created by HRegionServer
350-
// after RSRpcServices constructor and before start() is called.
351-
// Initialized only if authorization is enabled, else remains null.
352-
protected AccessChecker accessChecker;
350+
private AccessChecker accessChecker;
351+
private ZKPermissionWatcher zkPermissionWatcher;
353352

354353
/**
355354
* Services launched in RSRpcServices. By default they are on but you can use the below
@@ -1482,15 +1481,26 @@ private RegionServerSpaceQuotaManager getSpaceQuotaManager() {
14821481

14831482
void start(ZKWatcher zkWatcher) {
14841483
if (AccessChecker.isAuthorizationSupported(getConfiguration())) {
1485-
accessChecker = new AccessChecker(getConfiguration(), zkWatcher);
1484+
accessChecker = new AccessChecker(getConfiguration());
1485+
} else {
1486+
accessChecker = new NoopAccessChecker(getConfiguration());
1487+
}
1488+
if (!getConfiguration().getBoolean("hbase.testing.nocluster", false) && zkWatcher != null) {
1489+
zkPermissionWatcher =
1490+
new ZKPermissionWatcher(zkWatcher, accessChecker.getAuthManager(), getConfiguration());
1491+
try {
1492+
zkPermissionWatcher.start();
1493+
} catch (KeeperException e) {
1494+
LOG.error("ZooKeeper permission watcher initialization failed", e);
1495+
}
14861496
}
14871497
this.scannerIdGenerator = new ScannerIdGenerator(this.regionServer.serverName);
14881498
rpcServer.start();
14891499
}
14901500

14911501
void stop() {
1492-
if (accessChecker != null) {
1493-
accessChecker.stop();
1502+
if (zkPermissionWatcher != null) {
1503+
zkPermissionWatcher.close();
14941504
}
14951505
closeAllScanners();
14961506
rpcServer.stop();
@@ -3777,4 +3787,12 @@ public ExecuteProceduresResponse executeProcedures(RpcController controller,
37773787
public RpcScheduler getRpcScheduler() {
37783788
return rpcServer.getScheduler();
37793789
}
3790+
3791+
protected AccessChecker getAccessChecker() {
3792+
return accessChecker;
3793+
}
3794+
3795+
protected ZKPermissionWatcher getZkPermissionWatcher() {
3796+
return zkPermissionWatcher;
3797+
}
37803798
}

hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RegionServerServices.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@
4040
import org.apache.hadoop.hbase.quotas.RegionSizeStore;
4141
import org.apache.hadoop.hbase.regionserver.compactions.CompactionRequester;
4242
import org.apache.hadoop.hbase.regionserver.throttle.ThroughputController;
43+
import org.apache.hadoop.hbase.security.access.AccessChecker;
44+
import org.apache.hadoop.hbase.security.access.ZKPermissionWatcher;
4345
import org.apache.hadoop.hbase.wal.WAL;
4446
import org.apache.yetus.audience.InterfaceAudience;
4547

@@ -304,4 +306,14 @@ boolean reportFileArchivalForQuotas(
304306
* @return The cache for mob files.
305307
*/
306308
Optional<MobFileCache> getMobFileCache();
309+
310+
/**
311+
* @return the {@link AccessChecker}
312+
*/
313+
AccessChecker getAccessChecker();
314+
315+
/**
316+
* @return {@link ZKPermissionWatcher}
317+
*/
318+
ZKPermissionWatcher getZKPermissionWatcher();
307319
}

hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/AccessChecker.java

Lines changed: 4 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@
4444
import org.apache.hadoop.hbase.security.UserProvider;
4545
import org.apache.hadoop.hbase.security.access.Permission.Action;
4646
import org.apache.hadoop.hbase.util.Bytes;
47-
import org.apache.hadoop.hbase.zookeeper.ZKWatcher;
4847
import org.apache.hadoop.security.Groups;
4948
import org.apache.hadoop.security.HadoopKerberosName;
5049
import org.apache.yetus.audience.InterfaceAudience;
@@ -53,24 +52,15 @@
5352
import org.apache.hbase.thirdparty.com.google.common.collect.ImmutableSet;
5453

5554
@InterfaceAudience.Private
56-
public final class AccessChecker {
55+
public class AccessChecker {
5756
private static final Logger LOG = LoggerFactory.getLogger(AccessChecker.class);
5857
private static final Logger AUDITLOG =
5958
LoggerFactory.getLogger("SecurityLogger." + AccessChecker.class.getName());
60-
// TODO: we should move to a design where we don't even instantiate an AccessChecker if
61-
// authorization is not enabled (like in RSRpcServices), instead of always instantiating one and
62-
// calling requireXXX() only to do nothing (since authorizationEnabled will be false).
63-
private AuthManager authManager;
59+
private final AuthManager authManager;
6460

6561
/** Group service to retrieve the user group information */
6662
private static Groups groupService;
6763

68-
/**
69-
* if we are active, usually false, only true if "hbase.security.authorization"
70-
* has been set to true in site configuration.see HBASE-19483.
71-
*/
72-
private boolean authorizationEnabled;
73-
7464
public static boolean isAuthorizationSupported(Configuration conf) {
7565
return conf.getBoolean(User.HBASE_SECURITY_AUTHORIZATION_CONF_KEY, false);
7666
}
@@ -79,30 +69,12 @@ public static boolean isAuthorizationSupported(Configuration conf) {
7969
* Constructor with existing configuration
8070
*
8171
* @param conf Existing configuration to use
82-
* @param zkw reference to the {@link ZKWatcher}
8372
*/
84-
public AccessChecker(final Configuration conf, final ZKWatcher zkw)
85-
throws RuntimeException {
86-
if (zkw != null) {
87-
try {
88-
this.authManager = AuthManager.getOrCreate(zkw, conf);
89-
} catch (IOException ioe) {
90-
throw new RuntimeException("Error obtaining AccessChecker", ioe);
91-
}
92-
} else {
93-
throw new NullPointerException("Error obtaining AccessChecker, zk found null.");
94-
}
95-
authorizationEnabled = isAuthorizationSupported(conf);
73+
public AccessChecker(final Configuration conf) {
74+
this.authManager = new AuthManager(conf);
9675
initGroupService(conf);
9776
}
9877

99-
/**
100-
* Releases {@link AuthManager}'s reference.
101-
*/
102-
public void stop() {
103-
AuthManager.release(authManager);
104-
}
105-
10678
public AuthManager getAuthManager() {
10779
return authManager;
10880
}
@@ -119,9 +91,6 @@ public AuthManager getAuthManager() {
11991
*/
12092
public void requireAccess(User user, String request, TableName tableName,
12193
Action... permissions) throws IOException {
122-
if (!authorizationEnabled) {
123-
return;
124-
}
12594
AuthResult result = null;
12695

12796
for (Action permission : permissions) {
@@ -170,9 +139,6 @@ public void requirePermission(User user, String request, String filterUser, Acti
170139
public void requireGlobalPermission(User user, String request,
171140
Action perm, TableName tableName,
172141
Map<byte[], ? extends Collection<byte[]>> familyMap, String filterUser) throws IOException {
173-
if (!authorizationEnabled) {
174-
return;
175-
}
176142
AuthResult result;
177143
if (authManager.authorizeUserGlobal(user, perm)) {
178144
result = AuthResult.allow(request, "Global check allowed", user, perm, tableName, familyMap);
@@ -201,9 +167,6 @@ public void requireGlobalPermission(User user, String request,
201167
*/
202168
public void requireGlobalPermission(User user, String request, Action perm,
203169
String namespace) throws IOException {
204-
if (!authorizationEnabled) {
205-
return;
206-
}
207170
AuthResult authResult;
208171
if (authManager.authorizeUserGlobal(user, perm)) {
209172
authResult = AuthResult.allow(request, "Global check allowed", user, perm, null);
@@ -229,9 +192,6 @@ public void requireGlobalPermission(User user, String request, Action perm,
229192
*/
230193
public void requireNamespacePermission(User user, String request, String namespace,
231194
String filterUser, Action... permissions) throws IOException {
232-
if (!authorizationEnabled) {
233-
return;
234-
}
235195
AuthResult result = null;
236196

237197
for (Action permission : permissions) {
@@ -264,9 +224,6 @@ public void requireNamespacePermission(User user, String request, String namespa
264224
public void requireNamespacePermission(User user, String request, String namespace,
265225
TableName tableName, Map<byte[], ? extends Collection<byte[]>> familyMap,
266226
Action... permissions) throws IOException {
267-
if (!authorizationEnabled) {
268-
return;
269-
}
270227
AuthResult result = null;
271228

272229
for (Action permission : permissions) {
@@ -303,9 +260,6 @@ public void requireNamespacePermission(User user, String request, String namespa
303260
*/
304261
public void requirePermission(User user, String request, TableName tableName, byte[] family,
305262
byte[] qualifier, String filterUser, Action... permissions) throws IOException {
306-
if (!authorizationEnabled) {
307-
return;
308-
}
309263
AuthResult result = null;
310264

311265
for (Action permission : permissions) {
@@ -341,9 +295,6 @@ public void requirePermission(User user, String request, TableName tableName, by
341295
public void requireTablePermission(User user, String request,
342296
TableName tableName,byte[] family, byte[] qualifier,
343297
Action... permissions) throws IOException {
344-
if (!authorizationEnabled) {
345-
return;
346-
}
347298
AuthResult result = null;
348299

349300
for (Action permission : permissions) {
@@ -374,10 +325,6 @@ public void requireTablePermission(User user, String request,
374325
*/
375326
public void performOnSuperuser(String request, User caller, String userToBeChecked)
376327
throws IOException {
377-
if (!authorizationEnabled) {
378-
return;
379-
}
380-
381328
List<String> userGroups = new ArrayList<>();
382329
userGroups.add(userToBeChecked);
383330
if (!AuthUtil.isGroupPrincipal(userToBeChecked)) {
@@ -541,9 +488,6 @@ public static List<String> getUserGroups(String user) {
541488
* @return True if the user has the specific permission
542489
*/
543490
public boolean hasUserPermission(User user, String request, Permission permission) {
544-
if (!authorizationEnabled) {
545-
return true;
546-
}
547491
if (permission instanceof TablePermission) {
548492
TablePermission tPerm = (TablePermission) permission;
549493
for (Permission.Action action : permission.getActions()) {
@@ -609,10 +553,6 @@ private AuthResult permissionGranted(String request, User user, Action permReque
609553
*/
610554
public AuthResult permissionGranted(String request, User user, Action permRequest,
611555
TableName tableName, Map<byte[], ? extends Collection<?>> families) {
612-
if (!authorizationEnabled) {
613-
return AuthResult.allow(request, "All users allowed because authorization is disabled", user,
614-
permRequest, tableName, families);
615-
}
616556
// 1. All users need read access to hbase:meta table.
617557
// this is a very common operation, so deal with it quickly.
618558
if (TableName.META_TABLE_NAME.equals(tableName)) {

0 commit comments

Comments
 (0)