Repository: ranger Updated Branches: refs/heads/ranger-0.7 8040bf338 -> 29801e0e5
RANGER-2010 : Ranger Tagsync should use cookie based authentication for subsequent requests to Ranger admin Change-Id: If2c6357a31b60f3c36200d8fa40c1d6bb9905a11 Signed-off-by: pradeep <prad...@apache.org> Project: http://git-wip-us.apache.org/repos/asf/ranger/repo Commit: http://git-wip-us.apache.org/repos/asf/ranger/commit/2d35834d Tree: http://git-wip-us.apache.org/repos/asf/ranger/tree/2d35834d Diff: http://git-wip-us.apache.org/repos/asf/ranger/diff/2d35834d Branch: refs/heads/ranger-0.7 Commit: 2d35834d13125877424e0c25d6faa836461a772a Parents: 8040bf3 Author: Nikhil P <nikhil.pur...@gmail.com> Authored: Wed Mar 14 11:55:29 2018 +0530 Committer: Abhay Kulkarni <akulka...@hortonworks.com> Committed: Wed Sep 26 21:27:27 2018 -0700 ---------------------------------------------------------------------- .../ranger/plugin/util/RangerRESTClient.java | 4 + .../ranger/tagsync/process/TagSyncConfig.java | 8 +- .../tagsync/sink/tagadmin/TagAdminRESTSink.java | 147 ++++++++++++++++++- .../src/main/resources/ranger-tagsync-site.xml | 5 +- 4 files changed, 158 insertions(+), 6 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ranger/blob/2d35834d/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerRESTClient.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerRESTClient.java b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerRESTClient.java index 9395f28..c8b8935 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerRESTClient.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerRESTClient.java @@ -221,6 +221,10 @@ public class RangerRESTClient { return client; } + public void resetClient(){ + client = null; + } + private void init() { try { gsonBuilder = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ").setPrettyPrinting().create(); http://git-wip-us.apache.org/repos/asf/ranger/blob/2d35834d/tagsync/src/main/java/org/apache/ranger/tagsync/process/TagSyncConfig.java ---------------------------------------------------------------------- diff --git a/tagsync/src/main/java/org/apache/ranger/tagsync/process/TagSyncConfig.java b/tagsync/src/main/java/org/apache/ranger/tagsync/process/TagSyncConfig.java index 697c7cc..5f6079e 100644 --- a/tagsync/src/main/java/org/apache/ranger/tagsync/process/TagSyncConfig.java +++ b/tagsync/src/main/java/org/apache/ranger/tagsync/process/TagSyncConfig.java @@ -83,6 +83,7 @@ public class TagSyncConfig extends Configuration { private static final String TAGSYNC_SOURCE_RETRY_INITIALIZATION_INTERVAL_PROP = "ranger.tagsync.source.retry.initialization.interval.millis"; + public static final String TAGSYNC_RANGER_COOKIE_ENABLED_PROP = "ranger.tagsync.cookie.enabled"; private static final String DEFAULT_TAGADMIN_USERNAME = "rangertagsync"; private static final String DEFAULT_TAGADMIN_PASSWORD = "rangertagsync"; private static final String DEFAULT_ATLASREST_USERNAME = "admin"; @@ -205,7 +206,12 @@ public class TagSyncConfig extends Configuration { static public boolean isTagSyncEnabled(Properties prop) { String val = prop.getProperty(TAGSYNC_ENABLED_PROP); - return !(val != null && val.trim().equalsIgnoreCase("false")); + return val == null || Boolean.valueOf(val.trim()); + } + + static public boolean isTagSyncRangerCookieEnabled(Properties prop) { + String val = prop.getProperty(TAGSYNC_RANGER_COOKIE_ENABLED_PROP); + return val == null || Boolean.valueOf(val.trim()); } static public String getTagSyncLogdir(Properties prop) { http://git-wip-us.apache.org/repos/asf/ranger/blob/2d35834d/tagsync/src/main/java/org/apache/ranger/tagsync/sink/tagadmin/TagAdminRESTSink.java ---------------------------------------------------------------------- diff --git a/tagsync/src/main/java/org/apache/ranger/tagsync/sink/tagadmin/TagAdminRESTSink.java b/tagsync/src/main/java/org/apache/ranger/tagsync/sink/tagadmin/TagAdminRESTSink.java index c34b6ea..211d573 100644 --- a/tagsync/src/main/java/org/apache/ranger/tagsync/sink/tagadmin/TagAdminRESTSink.java +++ b/tagsync/src/main/java/org/apache/ranger/tagsync/sink/tagadmin/TagAdminRESTSink.java @@ -29,6 +29,11 @@ import org.apache.commons.logging.LogFactory; import org.apache.hadoop.security.UserGroupInformation; import org.apache.ranger.admin.client.datatype.RESTResponse; import org.apache.ranger.tagsync.model.TagSink; +import com.sun.jersey.api.client.Client; +import javax.ws.rs.core.Cookie; +import javax.ws.rs.core.NewCookie; +import java.util.ArrayList; +import java.util.List; import org.apache.ranger.plugin.util.RangerRESTClient; import org.apache.ranger.plugin.util.SearchFilter; import org.apache.ranger.plugin.util.ServiceTags; @@ -55,6 +60,14 @@ public class TagAdminRESTSink implements TagSink, Runnable { private long rangerAdminConnectionCheckInterval; + private Cookie sessionId=null; + + private boolean isValidRangerCookie=false; + + List<NewCookie> cookieList=new ArrayList<>(); + + private boolean isRangerCookieEnabled; + private RangerRESTClient tagRESTClient = null; private boolean isKerberized; @@ -77,7 +90,8 @@ public class TagAdminRESTSink implements TagSink, Runnable { String password = TagSyncConfig.getTagAdminPassword(properties); rangerAdminConnectionCheckInterval = TagSyncConfig.getTagAdminConnectionCheckInterval(properties); isKerberized = TagSyncConfig.getTagsyncKerberosIdentity(properties) != null; - + isRangerCookieEnabled = TagSyncConfig.isTagSyncRangerCookieEnabled(properties); + sessionId=null; if (LOG.isDebugEnabled()) { LOG.debug("restUrl=" + restUrl); @@ -172,9 +186,13 @@ public class TagAdminRESTSink implements TagSink, Runnable { if(LOG.isDebugEnabled()) { LOG.debug("==> doUpload()"); } - WebResource webResource = createWebResource(REST_URL_IMPORT_SERVICETAGS_RESOURCE); - - ClientResponse response = webResource.accept(REST_MIME_TYPE_JSON).type(REST_MIME_TYPE_JSON).put(ClientResponse.class, tagRESTClient.toJson(serviceTags)); + ClientResponse response = null; + if (isRangerCookieEnabled) { + response = uploadServiceTagsUsingCookie(serviceTags); + } else { + WebResource webResource = createWebResource(REST_URL_IMPORT_SERVICETAGS_RESOURCE); + response = webResource.accept(REST_MIME_TYPE_JSON).type(REST_MIME_TYPE_JSON).put(ClientResponse.class, tagRESTClient.toJson(serviceTags)); + } if(response == null || response.getStatus() != HttpServletResponse.SC_NO_CONTENT) { @@ -196,6 +214,120 @@ public class TagAdminRESTSink implements TagSink, Runnable { return serviceTags; } + private ClientResponse uploadServiceTagsUsingCookie(ServiceTags serviceTags) { + if (LOG.isDebugEnabled()) { + LOG.debug("==> uploadServiceTagCache()"); + } + ClientResponse clientResponse = null; + if (sessionId != null && isValidRangerCookie) { + clientResponse = tryWithCookie(serviceTags); + + } else { + clientResponse = tryWithCred(serviceTags); + } + if (LOG.isDebugEnabled()) { + LOG.debug("<== uploadServiceTagCache()"); + } + return clientResponse; + } + + private ClientResponse tryWithCred(ServiceTags serviceTags) { + if (LOG.isDebugEnabled()) { + LOG.debug("==> tryWithCred"); + } + ClientResponse clientResponsebyCred = uploadTagsWithCred(serviceTags); + if (clientResponsebyCred != null && clientResponsebyCred.getStatus() != HttpServletResponse.SC_NO_CONTENT + && clientResponsebyCred.getStatus() != HttpServletResponse.SC_BAD_REQUEST + && clientResponsebyCred.getStatus() != HttpServletResponse.SC_OK) { + sessionId = null; + clientResponsebyCred = null; + } + + if (LOG.isDebugEnabled()) { + LOG.debug("<== tryWithCred"); + } + return clientResponsebyCred; + } + + private ClientResponse tryWithCookie(ServiceTags serviceTags) { + ClientResponse clientResponsebySessionId = uploadTagsWithCookie(serviceTags); + if (clientResponsebySessionId != null + && clientResponsebySessionId.getStatus() != HttpServletResponse.SC_NO_CONTENT + && clientResponsebySessionId.getStatus() != HttpServletResponse.SC_BAD_REQUEST + && clientResponsebySessionId.getStatus() != HttpServletResponse.SC_OK) { + sessionId = null; + isValidRangerCookie = false; + clientResponsebySessionId = null; + } + return clientResponsebySessionId; + } + + private synchronized ClientResponse uploadTagsWithCred(ServiceTags serviceTags) { + if (sessionId == null) { + tagRESTClient.resetClient(); + WebResource webResource = createWebResource(REST_URL_IMPORT_SERVICETAGS_RESOURCE); + ClientResponse response = webResource.accept(REST_MIME_TYPE_JSON).type(REST_MIME_TYPE_JSON).put(ClientResponse.class, + tagRESTClient.toJson(serviceTags)); + if (response != null) { + if (!(response.toString().contains(REST_URL_IMPORT_SERVICETAGS_RESOURCE))) { + response.setStatus(HttpServletResponse.SC_NOT_FOUND); + } else if (response.getStatus() == HttpServletResponse.SC_UNAUTHORIZED) { + LOG.warn("Credentials response from ranger is 401."); + } else if (response.getStatus() == HttpServletResponse.SC_OK + || response.getStatus() == HttpServletResponse.SC_NO_CONTENT) { + cookieList = response.getCookies(); + // save cookie received from credentials session login + for (NewCookie cookie : cookieList) { + if (cookie.getName().equalsIgnoreCase("RANGERADMINSESSIONID")) { + sessionId = cookie.toCookie(); + isValidRangerCookie = true; + break; + } else { + isValidRangerCookie = false; + } + } + } + } + return response; + } else { + ClientResponse clientResponsebySessionId = uploadTagsWithCookie(serviceTags); + + if (!(clientResponsebySessionId.toString().contains(REST_URL_IMPORT_SERVICETAGS_RESOURCE))) { + clientResponsebySessionId.setStatus(HttpServletResponse.SC_NOT_FOUND); + } + return clientResponsebySessionId; + } + } + + private ClientResponse uploadTagsWithCookie(ServiceTags serviceTags) { + if (LOG.isDebugEnabled()) { + LOG.debug("==> uploadTagsWithCookie"); + } + WebResource webResource = createWebResourceForCookieAuth(REST_URL_IMPORT_SERVICETAGS_RESOURCE); + WebResource.Builder br = webResource.getRequestBuilder().cookie(sessionId); + ClientResponse response = br.accept(REST_MIME_TYPE_JSON).type(REST_MIME_TYPE_JSON).put(ClientResponse.class, + tagRESTClient.toJson(serviceTags)); + if (response != null) { + if (!(response.toString().contains(REST_URL_IMPORT_SERVICETAGS_RESOURCE))) { + response.setStatus(HttpServletResponse.SC_NOT_FOUND); + sessionId = null; + isValidRangerCookie = false; + } else if (response.getStatus() == HttpServletResponse.SC_UNAUTHORIZED) { + sessionId = null; + isValidRangerCookie = false; + } else if (response.getStatus() == HttpServletResponse.SC_NO_CONTENT + || response.getStatus() == HttpServletResponse.SC_OK) { + isValidRangerCookie = true; + } + + } + + if (LOG.isDebugEnabled()) { + LOG.debug("<== uploadTagsWithCookie"); + } + return response; + } + private WebResource createWebResource(String url) { return createWebResource(url, null); } @@ -215,6 +347,13 @@ public class TagAdminRESTSink implements TagSink, Runnable { return ret; } + private WebResource createWebResourceForCookieAuth(String url) { + Client cookieClient = tagRESTClient.getClient(); + cookieClient.removeAllFilters(); + WebResource ret = cookieClient.resource(tagRESTClient.getUrl() + url); + return ret; + } + @Override public boolean start() { http://git-wip-us.apache.org/repos/asf/ranger/blob/2d35834d/tagsync/src/main/resources/ranger-tagsync-site.xml ---------------------------------------------------------------------- diff --git a/tagsync/src/main/resources/ranger-tagsync-site.xml b/tagsync/src/main/resources/ranger-tagsync-site.xml index 3542ae2..ea36ed6 100644 --- a/tagsync/src/main/resources/ranger-tagsync-site.xml +++ b/tagsync/src/main/resources/ranger-tagsync-site.xml @@ -93,5 +93,8 @@ <name>ranger.tagsync.source.atlasrest.keystore.filename</name> <value>/etc/ranger/tagsync/conf/atlasuser.jceks</value> </property> - + <property> + <name>ranger.tagsync.cookie.enabled</name> + <value>true</value> + </property> </configuration>