Skip to content

Commit 5626b6e

Browse files
kumaabpradeepagrawal8184
authored andcommitted
RANGER-5488: Allow clients to access secure API endpoints in Ranger admin forcibly via config
1 parent a78984f commit 5626b6e

8 files changed

Lines changed: 126 additions & 158 deletions

File tree

agents-common/src/main/java/org/apache/ranger/admin/client/AbstractRangerAdminClient.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import com.google.gson.GsonBuilder;
2424
import org.apache.hadoop.conf.Configuration;
2525
import org.apache.hadoop.security.UserGroupInformation;
26+
import org.apache.ranger.audit.provider.MiscUtil;
2627
import org.apache.ranger.plugin.model.RangerRole;
2728
import org.apache.ranger.plugin.util.GrantRevokeRequest;
2829
import org.apache.ranger.plugin.util.GrantRevokeRoleRequest;
@@ -42,6 +43,7 @@ public abstract class AbstractRangerAdminClient implements RangerAdminClient {
4243
protected Gson gson;
4344

4445
private boolean forceNonKerberos;
46+
private boolean forceSecureEndpointAccess;
4547

4648
@Override
4749
public void init(String serviceName, String appId, String configPropertyPrefix, Configuration config) {
@@ -54,7 +56,8 @@ public void init(String serviceName, String appId, String configPropertyPrefix,
5456
}
5557

5658
this.gson = gson;
57-
this.forceNonKerberos = config.getBoolean(configPropertyPrefix + ".forceNonKerberos", false);
59+
this.forceNonKerberos = config.getBoolean(configPropertyPrefix + ".forceNonKerberos", false);
60+
this.forceSecureEndpointAccess = config.getBoolean(configPropertyPrefix + ".forceSecureEndpointAccess", false);
5861
}
5962

6063
@Override
@@ -127,12 +130,21 @@ public ServiceGdsInfo getGdsInfoIfUpdated(long lastKnownVersion, long lastActiva
127130
return null;
128131
}
129132

133+
public boolean isAuthenticationEnabled() {
134+
return forceSecureEndpointAccess || isKerberosEnabled();
135+
}
136+
137+
public boolean isKerberosEnabled() {
138+
return isKerberosEnabled(MiscUtil.getUGILoginUser());
139+
}
140+
130141
public boolean isKerberosEnabled(UserGroupInformation user) {
131142
final boolean ret;
132143

133144
if (forceNonKerberos) {
134145
ret = false;
135146
} else {
147+
LOG.debug("UGI user: {}", user);
136148
ret = user != null && UserGroupInformation.isSecurityEnabled() && user.hasKerberosCredentials();
137149
}
138150

agents-common/src/main/java/org/apache/ranger/admin/client/RangerAdminRESTClient.java

Lines changed: 79 additions & 92 deletions
Large diffs are not rendered by default.

agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPluginContext.java

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@
2323
import org.apache.ranger.admin.client.RangerAdminClient;
2424
import org.apache.ranger.admin.client.RangerAdminRESTClient;
2525
import org.apache.ranger.authorization.hadoop.config.RangerPluginConfig;
26-
import org.apache.ranger.plugin.authn.DefaultJwtProvider;
27-
import org.apache.ranger.plugin.authn.JwtProvider;
2826
import org.apache.ranger.plugin.model.RangerPolicy;
2927
import org.apache.ranger.plugin.resourcematcher.RangerResourceMatcher;
3028
import org.apache.ranger.plugin.service.RangerAuthContext;
@@ -42,14 +40,12 @@ public class RangerPluginContext {
4240
private final RangerPluginConfig config;
4341
private final Map<String, Map<RangerPolicy.RangerPolicyResource, RangerResourceMatcher>> resourceMatchers = new HashMap<>();
4442
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true); // fair lock
45-
private JwtProvider jwtProvider;
4643
private RangerAuthContext authContext;
4744
private RangerAuthContextListener authContextListener;
4845
private RangerAdminClient adminClient;
4946

5047
public RangerPluginContext(RangerPluginConfig config) {
5148
this.config = config;
52-
this.jwtProvider = new DefaultJwtProvider(config.getPropertyPrefix() + ".policy.rest.client", config);
5349
}
5450

5551
public RangerPluginConfig getConfig() {
@@ -155,9 +151,6 @@ public RangerAdminClient createAdminClient(RangerPluginConfig pluginConfig) {
155151

156152
if (ret == null) {
157153
ret = new RangerAdminRESTClient();
158-
if (jwtProvider != null) {
159-
((RangerAdminRESTClient) ret).setJwtProvider(jwtProvider);
160-
}
161154
}
162155

163156
ret.init(pluginConfig.getServiceName(), pluginConfig.getAppId(), pluginConfig.getPropertyPrefix(), pluginConfig);
@@ -170,19 +163,6 @@ public RangerAdminClient createAdminClient(RangerPluginConfig pluginConfig) {
170163
return ret;
171164
}
172165

173-
public void registerJWTProvider(JwtProvider jwtProvider) {
174-
this.jwtProvider = jwtProvider;
175-
176-
RangerAdminRESTClient restClient = (adminClient instanceof RangerAdminRESTClient) ? (RangerAdminRESTClient) adminClient : null;
177-
if (restClient != null) {
178-
restClient.setJwtProvider(jwtProvider);
179-
}
180-
}
181-
182-
public JwtProvider getJwtProvider() {
183-
return jwtProvider;
184-
}
185-
186166
void cleanResourceMatchers() {
187167
LOG.debug("==> cleanResourceMatchers()");
188168

agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
import org.apache.ranger.authorization.hadoop.config.RangerAuditConfig;
3333
import org.apache.ranger.authorization.hadoop.config.RangerPluginConfig;
3434
import org.apache.ranger.authorization.utils.StringUtil;
35-
import org.apache.ranger.plugin.authn.JwtProvider;
3635
import org.apache.ranger.plugin.contextenricher.RangerAdminGdsInfoRetriever;
3736
import org.apache.ranger.plugin.contextenricher.RangerAdminUserStoreRetriever;
3837
import org.apache.ranger.plugin.contextenricher.RangerContextEnricher;
@@ -303,10 +302,6 @@ public static RangerResourceACLs getMergedResourceACLs(RangerResourceACLs baseAC
303302
return baseACLs;
304303
}
305304

306-
public void registerJwtProvider(JwtProvider jwtProvider) {
307-
pluginContext.registerJWTProvider(jwtProvider);
308-
}
309-
310305
public String getServiceType() {
311306
return pluginConfig.getServiceType();
312307
}

agents-common/src/main/java/org/apache/ranger/plugin/util/RangerRESTClient.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ public class RangerRESTClient {
9898
private String mPassword;
9999
private boolean mIsSSL;
100100
private String jwt;
101+
private String authHeader;
101102
private String mKeyStoreURL;
102103
private String mKeyStoreAlias;
103104
private String mKeyStoreFile;
@@ -151,6 +152,10 @@ public String getPassword() {
151152
return mPassword;
152153
}
153154

155+
public boolean isAuthHeaderPresent() {
156+
return authHeader != null;
157+
}
158+
154159
public int getRestClientConnTimeOutMs() {
155160
return mRestClientConnTimeOutMs;
156161
}
@@ -278,7 +283,6 @@ public boolean verify(String urlHostName, SSLSession session) {
278283
// Validate that MOXy prevention is properly configured
279284
RangerJersey2ClientBuilder.validateAntiMoxyConfiguration(config);
280285

281-
final String authHeader;
282286
if (StringUtils.isNotEmpty(jwt)) { // use JWT if present
283287
authHeader = JWT_HEADER_PREFIX + jwt;
284288
LOG.info("Registering JWT auth header in REST client");

agents-common/src/test/java/org/apache/ranger/admin/client/TestAbstractRangerAdminClient.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,4 +95,13 @@ public void test03_defaultNoOpMethodsReturnNullOrNoThrow() throws Exception {
9595
Assertions.assertNull(c.getUserStoreIfUpdated(1L, 2L));
9696
Assertions.assertNull(c.getGdsInfoIfUpdated(1L, 2L));
9797
}
98+
99+
@Test
100+
void test04_isSecureEndpointAccess() {
101+
DummyClient c = new DummyClient();
102+
Configuration cfg = new Configuration(false);
103+
cfg.setBoolean("ranger.plugin.forceSecureEndpointAccess", true);
104+
c.init("svc", "app", "ranger.plugin", cfg);
105+
Assertions.assertTrue(c.isAuthenticationEnabled());
106+
}
98107
}

knox-agent/src/main/java/org/apache/ranger/admin/client/RangerAdminJersey2RESTClient.java

Lines changed: 16 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
import org.apache.commons.lang3.StringUtils;
2929
import org.apache.hadoop.conf.Configuration;
3030
import org.apache.hadoop.security.AccessControlException;
31-
import org.apache.hadoop.security.UserGroupInformation;
3231
import org.apache.ranger.audit.provider.MiscUtil;
3332
import org.apache.ranger.authorization.utils.StringUtil;
3433
import org.apache.ranger.plugin.util.GrantRevokeRequest;
@@ -287,8 +286,7 @@ public RangerUserStore getUserStoreIfUpdated(long lastKnownUserStoreVersion, lon
287286

288287
final RangerUserStore ret;
289288
final Response response;
290-
final UserGroupInformation user = MiscUtil.getUGILoginUser();
291-
final boolean isSecureMode = isKerberosEnabled(user);
289+
final boolean isSecureMode = isAuthenticationEnabled();
292290
Map<String, String> queryParams = new HashMap<>();
293291

294292
queryParams.put(RangerRESTUtils.REST_PARAM_LAST_KNOWN_USERSTORE_VERSION, Long.toString(lastKnownUserStoreVersion));
@@ -298,8 +296,6 @@ public RangerUserStore getUserStoreIfUpdated(long lastKnownUserStoreVersion, lon
298296
queryParams.put(RangerRESTUtils.REST_PARAM_CAPABILITIES, pluginCapabilities);
299297

300298
if (isSecureMode) {
301-
LOG.debug("Checking UserStore updated as user: {}", user);
302-
303299
response = MiscUtil.executePrivilegedAction((PrivilegedExceptionAction<Response>) () -> {
304300
try {
305301
String relativeURL = RangerRESTUtils.REST_URL_SERVICE_SERCURE_GET_USERSTORE + serviceNameUrlParam;
@@ -312,21 +308,18 @@ public RangerUserStore getUserStoreIfUpdated(long lastKnownUserStoreVersion, lon
312308
return null;
313309
});
314310
} else {
315-
LOG.debug("Checking UserStore updated as user: {}", user);
316-
317311
String relativeURL = RangerRESTUtils.REST_URL_SERVICE_GET_USERSTORE + serviceNameUrlParam;
318312

319313
response = get(queryParams, relativeURL);
320314
}
321315

322316
if (response == null || response.getStatus() == 304) { // NOT_MODIFIED
323317
if (response == null) {
324-
LOG.error("Error getting UserStore; Received NULL response!!. secureMode={}, user={}, serviceName={}", isSecureMode, user, serviceName);
318+
LOG.error("Error getting UserStore; Received NULL response!!. secureMode={}, serviceName={}", isSecureMode, serviceName);
325319
} else {
326320
String resp = response.hasEntity() ? response.readEntity(String.class) : null;
327321

328-
LOG.debug("No change in UserStore. secureMode={}, user={}, response={}, serviceName={}, lastKnownUserStoreVersion={}, lastActivationTimeInMillis={}",
329-
isSecureMode, user, resp, serviceName, lastKnownUserStoreVersion, lastActivationTimeInMillis);
322+
LOG.debug("No change in UserStore. secureMode={}, response={}, serviceName={}, lastKnownUserStoreVersion={}, lastActivationTimeInMillis={}", isSecureMode, resp, serviceName, lastKnownUserStoreVersion, lastActivationTimeInMillis);
330323
}
331324

332325
ret = null;
@@ -337,8 +330,7 @@ public RangerUserStore getUserStoreIfUpdated(long lastKnownUserStoreVersion, lon
337330
} else if (response.getStatus() == 404) { // NOT_FOUND
338331
ret = null;
339332

340-
LOG.error("Error getting UserStore; service not found. secureMode={}, user={}, response={}, serviceName={}, lastKnownUserStoreVersion={}, lastActivationTimeInMillis={}",
341-
isSecureMode, user, response.getStatus(), serviceName, lastKnownUserStoreVersion, lastActivationTimeInMillis);
333+
LOG.error("Error getting UserStore; service not found. secureMode={}, response={}, serviceName={}, lastKnownUserStoreVersion={}, lastActivationTimeInMillis={}", isSecureMode, response.getStatus(), serviceName, lastKnownUserStoreVersion, lastActivationTimeInMillis);
342334

343335
String exceptionMsg = response.hasEntity() ? response.readEntity(String.class) : null;
344336

@@ -348,8 +340,7 @@ public RangerUserStore getUserStoreIfUpdated(long lastKnownUserStoreVersion, lon
348340
} else {
349341
String resp = response.hasEntity() ? response.readEntity(String.class) : null;
350342

351-
LOG.warn("Error getting UserStore. secureMode={}, user={}, response={}, serviceName={}, lastKnownUserStoreVersion={}, lastActivationTimeInMillis={}",
352-
isSecureMode, user, resp, serviceName, lastKnownUserStoreVersion, lastActivationTimeInMillis);
343+
LOG.warn("Error getting UserStore. secureMode={}, response={}, serviceName={}, lastKnownUserStoreVersion={}, lastActivationTimeInMillis={}", isSecureMode, resp, serviceName, lastKnownUserStoreVersion, lastActivationTimeInMillis);
353344

354345
ret = null;
355346
}
@@ -601,7 +592,7 @@ private ServicePolicies getServicePoliciesIfUpdatedWithCred(final long lastKnown
601592
policyDownloadSessionId = null;
602593
body = response.readEntity(String.class);
603594

604-
LOG.warn("Unexpected: Received status[{}] with body[{}] form url[{}]", httpResponseCode, body, getRelativeURL(isSecureMode()));
595+
LOG.warn("Unexpected: Received status[{}] with body[{}] form url[{}]", httpResponseCode, body, getRelativeURL(isAuthenticationEnabled()));
605596
break;
606597
}
607598

@@ -667,7 +658,7 @@ private ServicePolicies getServicePoliciesIfUpdatedWithCookie(final long lastKno
667658
isValidPolicyDownloadSessionCookie = false;
668659
body = response.readEntity(String.class);
669660

670-
LOG.warn("Unexpected: Received status[{}] with body[{}] form url[{}]", httpResponseCode, body, getRelativeURL(isSecureMode()));
661+
LOG.warn("Unexpected: Received status[{}] with body[{}] form url[{}]", httpResponseCode, body, getRelativeURL(isAuthenticationEnabled()));
671662
break;
672663
}
673664

@@ -689,10 +680,8 @@ private Response getRangerAdminPolicyDownloadResponse(final long lastKnownVersio
689680
queryParams.put(RangerRESTUtils.REST_PARAM_SUPPORTS_POLICY_DELTAS, Boolean.toString(supportsPolicyDeltas));
690681
queryParams.put(RangerRESTUtils.REST_PARAM_CAPABILITIES, pluginCapabilities);
691682

692-
if (isSecureMode()) {
693-
if (LOG.isDebugEnabled()) {
694-
LOG.debug("Checking Service policy if updated as user : {}", MiscUtil.getUGILoginUser());
695-
}
683+
if (isAuthenticationEnabled()) {
684+
LOG.debug("Checking Service policy if updated");
696685

697686
ret = MiscUtil.executePrivilegedAction((PrivilegedExceptionAction<Response>) () -> get(queryParams, getRelativeURL(true), policyDownloadSessionId));
698687
} else {
@@ -806,7 +795,7 @@ private ServiceTags getServiceTagsIfUpdatedWithCred(final long lastKnownVersion,
806795
tagDownloadSessionId = null;
807796
body = response.readEntity(String.class);
808797

809-
LOG.warn("Unexpected: Received status[{}] with body[{}] form url[{}]", httpResponseCode, body, getRelativeURLForTagDownload(isSecureMode()));
798+
LOG.warn("Unexpected: Received status[{}] with body[{}] form url[{}]", httpResponseCode, body, getRelativeURLForTagDownload(isAuthenticationEnabled()));
810799
break;
811800
}
812801

@@ -893,10 +882,8 @@ private Response getTagsDownloadResponse(final long lastKnownVersion, final long
893882
queryParams.put(RangerRESTUtils.REST_PARAM_SUPPORTS_TAG_DELTAS, Boolean.toString(supportsTagDeltas));
894883
queryParams.put(RangerRESTUtils.REST_PARAM_CAPABILITIES, pluginCapabilities);
895884

896-
if (isSecureMode()) {
897-
if (LOG.isDebugEnabled()) {
898-
LOG.debug("Checking Service tags if updated as user : {}", MiscUtil.getUGILoginUser());
899-
}
885+
if (isAuthenticationEnabled()) {
886+
LOG.debug("Checking Service tags if updated");
900887

901888
ret = MiscUtil.executePrivilegedAction((PrivilegedExceptionAction<Response>) () -> get(queryParams, getRelativeURLForTagDownload(true), tagDownloadSessionId));
902889
} else {
@@ -1008,7 +995,7 @@ private RangerRoles getRangerRolesIfUpdatedWithCred(final long lastKnownRoleVers
1008995
roleDownloadSessionId = null;
1009996
body = response.readEntity(String.class);
1010997

1011-
LOG.warn("Unexpected: Received status[{}] with body[{}] form url[{}]", httpResponseCode, body, getRelativeURLForRoleDownload(isSecureMode()));
998+
LOG.warn("Unexpected: Received status[{}] with body[{}] form url[{}]", httpResponseCode, body, getRelativeURLForRoleDownload(isAuthenticationEnabled()));
1012999

10131000
break;
10141001
}
@@ -1075,7 +1062,7 @@ private RangerRoles getRangerRolesIfUpdatedWithCookie(final long lastKnownRoleVe
10751062
isValidRoleDownloadSessionCookie = false;
10761063
body = response.readEntity(String.class);
10771064

1078-
LOG.warn("Unexpected: Received status[{}] with body[{}] form url[{}]", httpResponseCode, body, getRelativeURLForRoleDownload(isSecureMode()));
1065+
LOG.warn("Unexpected: Received status[{}] with body[{}] form url[{}]", httpResponseCode, body, getRelativeURLForRoleDownload(isAuthenticationEnabled()));
10791066

10801067
break;
10811068
}
@@ -1096,10 +1083,8 @@ private Response getRoleDownloadResponse(final long lastKnownRoleVersion, final
10961083
queryParams.put(RangerRESTUtils.REST_PARAM_PLUGIN_ID, pluginId);
10971084
queryParams.put(RangerRESTUtils.REST_PARAM_CLUSTER_NAME, clusterName);
10981085

1099-
if (isSecureMode()) {
1100-
if (LOG.isDebugEnabled()) {
1101-
LOG.debug("Checking Roles if updated as user : {}", MiscUtil.getUGILoginUser());
1102-
}
1086+
if (isAuthenticationEnabled()) {
1087+
LOG.debug("Checking Roles if updated");
11031088

11041089
ret = MiscUtil.executePrivilegedAction((PrivilegedExceptionAction<Response>) () -> get(queryParams, getRelativeURLForRoleDownload(true), roleDownloadSessionId));
11051090
} else {
@@ -1158,10 +1143,6 @@ private void setCookieReceivedFromRoleDownloadSession(Response response) {
11581143
}
11591144
}
11601145

1161-
private boolean isSecureMode() {
1162-
return isKerberosEnabled(MiscUtil.getUGILoginUser());
1163-
}
1164-
11651146
// We get date from the policy manager as unix long! This deserializer exists to deal with it. Remove this class once we start send date/time per RFC 3339
11661147
public static class GsonUnixDateDeserializer implements JsonDeserializer<Date> {
11671148
@Override

knox-agent/src/test/java/org/apache/ranger/admin/client/TestRangerAdminJersey2RESTClient.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,7 @@ public void test12_policies_secure_mode_uses_secure_url() throws Exception {
418418
RangerAdminJersey2RESTClient underTest = spy(new RangerAdminJersey2RESTClient());
419419
underTest.client = clientMock;
420420
underTest.init(SERVICE, APPID, PREFIX, conf);
421-
doReturn(true).when(underTest).isKerberosEnabled(ArgumentMatchers.any());
421+
doReturn(true).when(underTest).isKerberosEnabled();
422422

423423
Map<String, NewCookie> cookies = new HashMap<>();
424424
cookies.put(COOKIE_NAME, new NewCookie(COOKIE_NAME, "v"));
@@ -457,7 +457,7 @@ public void test13_tags_secure_mode_uses_secure_url() throws Exception {
457457
RangerAdminJersey2RESTClient underTest = spy(new RangerAdminJersey2RESTClient());
458458
underTest.client = clientMock;
459459
underTest.init(SERVICE, APPID, PREFIX, conf);
460-
doReturn(true).when(underTest).isKerberosEnabled(ArgumentMatchers.any());
460+
doReturn(true).when(underTest).isKerberosEnabled();
461461

462462
Map<String, NewCookie> cookies = new HashMap<>();
463463
cookies.put(COOKIE_NAME, new NewCookie(COOKIE_NAME, "v"));
@@ -495,7 +495,7 @@ public void test14_roles_secure_mode_uses_secure_url() throws Exception {
495495
RangerAdminJersey2RESTClient underTest = spy(new RangerAdminJersey2RESTClient());
496496
underTest.client = clientMock;
497497
underTest.init(SERVICE, APPID, PREFIX, conf);
498-
doReturn(true).when(underTest).isKerberosEnabled(ArgumentMatchers.any());
498+
doReturn(true).when(underTest).isKerberosEnabled();
499499

500500
Map<String, NewCookie> cookies = new HashMap<>();
501501
cookies.put(COOKIE_NAME, new NewCookie(COOKIE_NAME, "v"));
@@ -533,7 +533,7 @@ public void test15_userstore_secure_mode_uses_secure_url() throws Exception {
533533
RangerAdminJersey2RESTClient underTest = spy(new RangerAdminJersey2RESTClient());
534534
underTest.client = clientMock;
535535
underTest.init(SERVICE, APPID, PREFIX, conf);
536-
doReturn(true).when(underTest).isKerberosEnabled(ArgumentMatchers.any());
536+
doReturn(true).when(underTest).isKerberosEnabled();
537537

538538
when(response200.getStatus()).thenReturn(200);
539539
when(response200.readEntity(String.class)).thenReturn("{}");

0 commit comments

Comments
 (0)